A Discrete-Event Network Simulator
API
tuple.h
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2021 Universita' degli Studi di Napoli Federico II
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: Stefano Avallone <stavallo@unina.it>
19  */
20 
21 #ifndef TUPLE_H
22 #define TUPLE_H
23 
24 #include <ns3/attribute-helper.h>
25 #include <ns3/string.h>
26 
27 #include <sstream>
28 #include <type_traits>
29 #include <utility>
30 #include <tuple>
31 #include <algorithm>
32 
33 namespace ns3 {
34 
47 template <class... Args>
48 std::ostream &
49 operator << (std::ostream &os, const std::tuple<Args...> &t)
50 {
51  std::apply ([&os](auto&&... args)
52  {
53  std::size_t n{0};
54  ((os << args << (++n != sizeof...(Args) ? ", " : "")), ...);
55  },
56  t);
57  return os;
58 }
59 
60 
61 // Doxygen for this class is auto-generated by
62 // utils/print-introspected-doxygen.h
63 
68 template <class... Args>
69 class TupleValue : public AttributeValue
70 {
71 public:
73  typedef std::tuple<Args...> value_type;
75  typedef std::tuple<std::invoke_result_t<decltype(&Args::Get),Args>...> result_type;
76 
77  TupleValue ();
78 
84  TupleValue (const result_type &value);
85 
86  Ptr<AttributeValue> Copy (void) const override;
87  bool DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker) override;
88  std::string SerializeToString (Ptr<const AttributeChecker> checker) const override;
89 
97  result_type Get (void) const;
101  void Set (const result_type &value);
102 
107  value_type GetValue (void) const;
108 
116  template <typename T>
117  bool GetAccessor (T &value) const;
118 
119 private:
128  template <std::size_t... Is>
129  bool SetValueImpl (std::index_sequence<Is...>, const std::vector<Ptr<AttributeValue>>& values);
130 
132 };
133 
149 template <class T1, class T2>
150 auto MakeTupleValue (T2 t);
151 
152 
157 {
158 public:
164  virtual const std::vector<Ptr<const AttributeChecker>>& GetCheckers (void) const = 0;
165 };
166 
167 
176 template <class... Args, class... Ts>
178 
179 
191 template <class... Args, class T1>
193 
206 template <class... Args, class T1, class T2>
208 
209 
210 } // namespace ns3
211 
212 /*****************************************************************************
213  * Implementation below
214  *****************************************************************************/
215 
216 namespace ns3 {
217 
218 template <class... Args>
220  : m_value (std::make_tuple (Args ()...))
221 {
222 }
223 
224 template <class... Args>
226 {
227  Set (value);
228 }
229 
230 template <class... Args>
233 {
234  return Create <TupleValue <Args...>> (Get ());
235 }
236 
237 template <class... Args>
238 template <std::size_t... Is>
239 bool
240 TupleValue<Args...>::SetValueImpl (std::index_sequence<Is...>, const std::vector<Ptr<AttributeValue>>& values)
241 {
242  auto valueTuple = std::make_tuple (DynamicCast<Args> (values[Is])...);
243 
244  bool ok = ((std::get<Is> (valueTuple) != nullptr) && ...);
245 
246  if (ok)
247  {
248  m_value = std::make_tuple (Args (*std::get<Is> (valueTuple))...);
249  }
250  return ok;
251 }
252 
253 template <class... Args>
254 bool
256 {
257  auto tupleChecker = DynamicCast<const TupleChecker> (checker);
258  if (tupleChecker == nullptr)
259  {
260  return false;
261  }
262 
263  auto count = tupleChecker->GetCheckers ().size ();
264  if (count != sizeof...(Args))
265  {
266  return false;
267  }
268 
269  if (value.empty () || value.front () != '{' || value.back () != '}')
270  {
271  return false;
272  }
273 
274  value.erase (value.begin ());
275  value.pop_back ();
276  std::replace (value.data (), value.data () + value.size (), ',', ' ');
277 
278  std::istringstream iss (value);
279  std::vector<Ptr<AttributeValue>> values;
280  std::size_t i = 0;
281 
282  while (iss >> value)
283  {
284  if (i >= count)
285  {
286  return false;
287  }
288  values.push_back (tupleChecker->GetCheckers ().at (i++)->CreateValidValue (StringValue (value)));
289  if (values.back () == nullptr)
290  {
291  return false;
292  }
293  }
294 
295  if (i != count)
296  {
297  return false;
298  }
299 
300  return SetValueImpl (std::index_sequence_for<Args...>{}, values);
301 }
302 
303 template <class... Args>
304 std::string
306 {
307  std::ostringstream oss;
308  oss << "{" << Get () << "}";
309  return oss.str ();
310 }
311 
312 template <class... Args>
313 typename TupleValue<Args...>::result_type
315 {
316  return std::apply ([](Args... values)
317  {
318  return std::make_tuple (values.Get ()...);
319  },
320  m_value);
321 }
322 
323 template <class... Args>
324 void
326 {
327  m_value = std::apply ([](auto&&... args)
328  {
329  return std::make_tuple (Args (args)...);
330  },
331  value);
332 }
333 
334 template <class... Args>
335 typename TupleValue<Args...>::value_type
337 {
338  return m_value;
339 }
340 
341 template <class... Args>
342 template <typename T>
343 bool
345 {
346  value = T (Get ());
347  return true;
348 }
349 
350 
351 
352 
353 // This internal class defines templated TupleChecker class that is instantiated
354 // in MakeTupleChecker. The non-templated base ns3::TupleChecker is returned in that
355 // function. This is the same pattern as ObjectPtrContainer.
356 namespace internal {
357 
362 template <class... Args>
364 {
365 public:
371  template <class... Ts>
372  TupleChecker (Ts... checkers)
373  : m_checkers {checkers...}
374  {
375  }
376  const std::vector<Ptr<const AttributeChecker>>& GetCheckers (void) const override
377  {
378  return m_checkers;
379  }
380  bool Check (const AttributeValue &value) const override
381  {
382  const TupleValue<Args...>* v = dynamic_cast<const TupleValue<Args...>*> (&value);
383  if (v == nullptr)
384  {
385  return false;
386  }
387  return std::apply ([this](Args... values)
388  {
389  std::size_t n{0};
390  return (m_checkers[n++]->Check (values) && ...);
391  },
392  v->GetValue ());
393  }
394  std::string GetValueTypeName (void) const override
395  {
396  return "ns3::TupleValue";
397  }
398  bool HasUnderlyingTypeInformation (void) const override
399  {
400  return false;
401  }
402  std::string GetUnderlyingTypeInformation (void) const override
403  {
404  return "";
405  }
406  Ptr<AttributeValue> Create (void) const override
407  {
408  return ns3::Create<TupleValue<Args...>> ();
409  }
410  bool Copy (const AttributeValue &source, AttributeValue &destination) const override
411  {
412  const TupleValue<Args...> *src = dynamic_cast<const TupleValue<Args...> *> (&source);
413  TupleValue<Args...> *dst = dynamic_cast<TupleValue<Args...> *> (&destination);
414  if (src == 0 || dst == 0)
415  {
416  return false;
417  }
418  *dst = *src;
419  return true;
420  }
421 
422 private:
423  std::vector<Ptr<const AttributeChecker>> m_checkers;
424 };
425 
431 template <class... Args>
433 {
437  template <class... Ts>
439  {
440  return Create <internal::TupleChecker<Args...>> (checkers...);
441  }
445  template <class T1>
447  {
448  return MakeAccessorHelper<TupleValue<Args...>> (a1);
449  }
453  template <class T1, class T2>
455  {
456  return MakeAccessorHelper<TupleValue<Args...>> (a1, a2);
457  }
458 };
459 
466 template <class... Args>
467 struct TupleHelper<std::tuple<Args...>>
468 {
472  static TupleValue<Args...> MakeTupleValue (const typename TupleValue<Args...>::result_type& t)
473  {
474  return TupleValue<Args...> (t);
475  }
479  template <class... Ts>
481  {
482  return Create <internal::TupleChecker<Args...>> (checkers...);
483  }
487  template <class T1>
489  {
490  return MakeAccessorHelper<TupleValue<Args...>> (a1);
491  }
495  template <class T1, class T2>
497  {
498  return MakeAccessorHelper<TupleValue<Args...>> (a1, a2);
499  }
500 };
501 
502 } // namespace internal
503 
504 
505 
506 template <class T1, class T2>
507 auto MakeTupleValue (T2 t)
508 {
510 }
511 
512 template <class... Args, class... Ts>
514 {
515  return internal::TupleHelper<Args...>::template MakeTupleChecker<Ts...> (checkers...);
516 }
517 
518 template <class... Args, class T1>
520 {
521  return internal::TupleHelper<Args...>::template MakeTupleAccessor<T1> (a1);
522 }
523 
524 template <class... Args, class T1, class T2>
526 {
527  return internal::TupleHelper<Args...>::template MakeTupleAccessor<T1, T2> (a1, a2);
528 }
529 
530 
531 
532 } // namespace ns3
533 
534 #endif // TUPLE_H
Represent the type of an attribute.
Definition: attribute.h:167
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
Checker for attribute values storing tuples.
Definition: tuple.h:157
virtual const std::vector< Ptr< const AttributeChecker > > & GetCheckers(void) const =0
Get the checkers for all tuple elements.
Hold objects of type std::tuple<Args...>.
Definition: tuple.h:70
bool DeserializeFromString(std::string value, Ptr< const AttributeChecker > checker) override
Definition: tuple.h:255
std::string SerializeToString(Ptr< const AttributeChecker > checker) const override
Definition: tuple.h:305
result_type Get(void) const
Get the stored values as a std::tuple.
Definition: tuple.h:314
Ptr< AttributeValue > Copy(void) const override
Definition: tuple.h:232
bool SetValueImpl(std::index_sequence< Is... >, const std::vector< Ptr< AttributeValue >> &values)
Set the attribute values starting from the given values.
Definition: tuple.h:240
void Set(const result_type &value)
Set the stored values.
Definition: tuple.h:325
bool GetAccessor(T &value) const
Set the given variable to the values stored by this TupleValue object.
Definition: tuple.h:344
std::tuple< Args... > value_type
Type of value stored in the TupleValue.
Definition: tuple.h:73
value_type GetValue(void) const
Get the attribute values as a tuple.
Definition: tuple.h:336
std::tuple< std::invoke_result_t< decltype(&Args::Get), Args >... > result_type
Type returned by Get or passed in Set.
Definition: tuple.h:75
value_type m_value
Tuple of attribute values.
Definition: tuple.h:131
Internal checker class templated to each AttributeChecker for each entry in the tuple.
Definition: tuple.h:364
std::string GetValueTypeName(void) const override
Definition: tuple.h:394
Ptr< AttributeValue > Create(void) const override
Definition: tuple.h:406
bool HasUnderlyingTypeInformation(void) const override
Definition: tuple.h:398
const std::vector< Ptr< const AttributeChecker > > & GetCheckers(void) const override
Get the checkers for all tuple elements.
Definition: tuple.h:376
std::vector< Ptr< const AttributeChecker > > m_checkers
attribute checkers
Definition: tuple.h:423
TupleChecker(Ts... checkers)
Constructor.
Definition: tuple.h:372
bool Check(const AttributeValue &value) const override
Definition: tuple.h:380
std::string GetUnderlyingTypeInformation(void) const override
Definition: tuple.h:402
bool Copy(const AttributeValue &source, AttributeValue &destination) const override
Copy the source to the destination.
Definition: tuple.h:410
Ptr< const AttributeAccessor > MakeAccessorHelper(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
void Set(std::string path, const AttributeValue &value)
Definition: config.cc:839
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition: ptr.h:409
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeTupleChecker(Ts... checkers)
Create a TupleChecker from AttributeCheckers associated with TupleValue elements.
Definition: tuple.h:513
Ptr< const AttributeAccessor > MakeTupleAccessor(T1 a1)
Create an AttributeAccessor for a class data member of type tuple, or a lone class get functor or set...
Definition: tuple.h:519
Ptr< const AttributeAccessor > MakeTupleAccessor(T1 a1, T2 a2)
Create an AttributeAccessor using a pair of get functor and set methods from a class.
Definition: tuple.h:525
auto MakeTupleValue(T2 t)
Create a TupleValue object.
Definition: tuple.h:507
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:139
static Ptr< const AttributeAccessor > MakeTupleAccessor(T1 a1)
Create an AttributeAccessor for a class data member of type tuple, or a lone class get functor or set...
Definition: tuple.h:488
static Ptr< const AttributeChecker > MakeTupleChecker(Ts... checkers)
Create a TupleChecker from AttributeCheckers associated with TupleValue elements.
Definition: tuple.h:480
static Ptr< const AttributeAccessor > MakeTupleAccessor(T1 a1, T2 a2)
Create an AttributeAccessor using a pair of get functor and set methods from a class.
Definition: tuple.h:496
static TupleValue< Args... > MakeTupleValue(const typename TupleValue< Args... >::result_type &t)
Create a TupleValue object.
Definition: tuple.h:472
Helper class defining static methods for MakeTupleChecker and MakeTupleAccessor that are called when ...
Definition: tuple.h:433
static Ptr< const AttributeChecker > MakeTupleChecker(Ts... checkers)
Create a TupleChecker from AttributeCheckers associated with TupleValue elements.
Definition: tuple.h:438
static Ptr< const AttributeAccessor > MakeTupleAccessor(T1 a1)
Create an AttributeAccessor for a class data member of type tuple, or a lone class get functor or set...
Definition: tuple.h:446
static Ptr< const AttributeAccessor > MakeTupleAccessor(T1 a1, T2 a2)
Create an AttributeAccessor using a pair of get functor and set methods from a class.
Definition: tuple.h:454