A Discrete-Event Network Simulator
API
tuple.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021 Universita' degli Studi di Napoli Federico II
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: Stefano Avallone <stavallo@unina.it>
18  */
19 
20 #ifndef TUPLE_H
21 #define TUPLE_H
22 
23 #include "attribute-helper.h"
24 #include "string.h"
25 
26 #include <algorithm>
27 #include <sstream>
28 #include <tuple>
29 #include <type_traits>
30 #include <utility>
31 
32 namespace ns3
33 {
34 
47 template <class... Args>
48 std::ostream&
49 operator<<(std::ostream& os, const std::tuple<Args...>& t)
50 {
51  std::apply(
52  [&os](auto&&... args) {
53  std::size_t n{0};
54  ((os << args << (++n != sizeof...(Args) ? ", " : "")), ...);
55  },
56  t);
57  return os;
58 }
59 
60 // Doxygen for this class is auto-generated by
61 // utils/print-introspected-doxygen.h
62 
67 template <class... Args>
68 class TupleValue : public AttributeValue
69 {
70  public:
72  typedef std::tuple<Args...> value_type;
74  typedef std::tuple<std::invoke_result_t<decltype(&Args::Get), Args>...> result_type;
75 
76  TupleValue();
77 
83  TupleValue(const result_type& value);
84 
85  Ptr<AttributeValue> Copy() const override;
86  bool DeserializeFromString(std::string value, Ptr<const AttributeChecker> checker) override;
87  std::string SerializeToString(Ptr<const AttributeChecker> checker) const override;
88 
96  result_type Get() const;
100  void Set(const result_type& value);
101 
106  value_type GetValue() const;
107 
115  template <typename T>
116  bool GetAccessor(T& value) const;
117 
118  private:
127  template <std::size_t... Is>
128  bool SetValueImpl(std::index_sequence<Is...>, const std::vector<Ptr<AttributeValue>>& values);
129 
131 };
132 
148 template <class T1, class T2>
149 auto MakeTupleValue(T2 t);
150 
155 {
156  public:
162  virtual const std::vector<Ptr<const AttributeChecker>>& GetCheckers() const = 0;
163 };
164 
173 template <class... Args, class... Ts>
175 
187 template <class... Args, class T1>
189 
202 template <class... Args, class T1, class T2>
204 
205 } // namespace ns3
206 
207 /*****************************************************************************
208  * Implementation below
209  *****************************************************************************/
210 
211 namespace ns3
212 {
213 
214 template <class... Args>
216  : m_value(std::make_tuple(Args()...))
217 {
218 }
219 
220 template <class... Args>
222 {
223  Set(value);
224 }
225 
226 template <class... Args>
229 {
230  return Create<TupleValue<Args...>>(Get());
231 }
232 
233 template <class... Args>
234 template <std::size_t... Is>
235 bool
236 TupleValue<Args...>::SetValueImpl(std::index_sequence<Is...>,
237  const std::vector<Ptr<AttributeValue>>& values)
238 {
239  auto valueTuple = std::make_tuple(DynamicCast<Args>(values[Is])...);
240 
241  bool ok = ((std::get<Is>(valueTuple) != nullptr) && ...);
242 
243  if (ok)
244  {
245  m_value = std::make_tuple(Args(*std::get<Is>(valueTuple))...);
246  }
247  return ok;
248 }
249 
250 template <class... Args>
251 bool
253 {
254  auto tupleChecker = DynamicCast<const TupleChecker>(checker);
255  if (!tupleChecker)
256  {
257  return false;
258  }
259 
260  auto count = tupleChecker->GetCheckers().size();
261  if (count != sizeof...(Args))
262  {
263  return false;
264  }
265 
266  if (value.empty() || value.front() != '{' || value.back() != '}')
267  {
268  return false;
269  }
270 
271  value.erase(value.begin());
272  value.pop_back();
273  std::replace(value.data(), value.data() + value.size(), ',', ' ');
274 
275  std::istringstream iss(value);
276  std::vector<Ptr<AttributeValue>> values;
277  std::size_t i = 0;
278 
279  while (iss >> value)
280  {
281  if (i >= count)
282  {
283  return false;
284  }
285  values.push_back(tupleChecker->GetCheckers().at(i++)->CreateValidValue(StringValue(value)));
286  if (!values.back())
287  {
288  return false;
289  }
290  }
291 
292  if (i != count)
293  {
294  return false;
295  }
296 
297  return SetValueImpl(std::index_sequence_for<Args...>{}, values);
298 }
299 
300 template <class... Args>
301 std::string
303 {
304  std::ostringstream oss;
305  oss << "{" << Get() << "}";
306  return oss.str();
307 }
308 
309 template <class... Args>
310 typename TupleValue<Args...>::result_type
312 {
313  return std::apply([](Args... values) { return std::make_tuple(values.Get()...); }, m_value);
314 }
315 
316 template <class... Args>
317 void
319 {
320  m_value = std::apply([](auto&&... args) { return std::make_tuple(Args(args)...); }, value);
321 }
322 
323 template <class... Args>
324 typename TupleValue<Args...>::value_type
326 {
327  return m_value;
328 }
329 
330 template <class... Args>
331 template <typename T>
332 bool
334 {
335  value = T(Get());
336  return true;
337 }
338 
339 // This internal class defines templated TupleChecker class that is instantiated
340 // in MakeTupleChecker. The non-templated base ns3::TupleChecker is returned in that
341 // function. This is the same pattern as ObjectPtrContainer.
342 namespace internal
343 {
344 
349 template <class... Args>
351 {
352  public:
358  template <class... Ts>
359  TupleChecker(Ts... checkers)
360  : m_checkers{checkers...}
361  {
362  }
363 
364  const std::vector<Ptr<const AttributeChecker>>& GetCheckers() const override
365  {
366  return m_checkers;
367  }
368 
369  bool Check(const AttributeValue& value) const override
370  {
371  const auto v = dynamic_cast<const TupleValue<Args...>*>(&value);
372  if (v == nullptr)
373  {
374  return false;
375  }
376  return std::apply(
377  [this](Args... values) {
378  std::size_t n{0};
379  return (m_checkers[n++]->Check(values) && ...);
380  },
381  v->GetValue());
382  }
383 
384  std::string GetValueTypeName() const override
385  {
386  return "ns3::TupleValue";
387  }
388 
389  bool HasUnderlyingTypeInformation() const override
390  {
391  return false;
392  }
393 
394  std::string GetUnderlyingTypeInformation() const override
395  {
396  return "";
397  }
398 
399  Ptr<AttributeValue> Create() const override
400  {
401  return ns3::Create<TupleValue<Args...>>();
402  }
403 
404  bool Copy(const AttributeValue& source, AttributeValue& destination) const override
405  {
406  const auto src = dynamic_cast<const TupleValue<Args...>*>(&source);
407  auto dst = dynamic_cast<TupleValue<Args...>*>(&destination);
408  if (src == nullptr || dst == nullptr)
409  {
410  return false;
411  }
412  *dst = *src;
413  return true;
414  }
415 
416  private:
417  std::vector<Ptr<const AttributeChecker>> m_checkers;
418 };
419 
425 template <class... Args>
427 {
431  template <class... Ts>
433  {
434  return Create<internal::TupleChecker<Args...>>(checkers...);
435  }
436 
440  template <class T1>
442  {
443  return MakeAccessorHelper<TupleValue<Args...>>(a1);
444  }
445 
449  template <class T1, class T2>
451  {
452  return MakeAccessorHelper<TupleValue<Args...>>(a1, a2);
453  }
454 };
455 
462 template <class... Args>
463 struct TupleHelper<std::tuple<Args...>>
464 {
468  static TupleValue<Args...> MakeTupleValue(const typename TupleValue<Args...>::result_type& t)
469  {
470  return TupleValue<Args...>(t);
471  }
472 
476  template <class... Ts>
478  {
479  return Create<internal::TupleChecker<Args...>>(checkers...);
480  }
481 
485  template <class T1>
487  {
488  return MakeAccessorHelper<TupleValue<Args...>>(a1);
489  }
490 
494  template <class T1, class T2>
496  {
497  return MakeAccessorHelper<TupleValue<Args...>>(a1, a2);
498  }
499 };
500 
501 } // namespace internal
502 
503 template <class T1, class T2>
504 auto
506 {
508 }
509 
510 template <class... Args, class... Ts>
511 Ptr<const AttributeChecker>
512 MakeTupleChecker(Ts... checkers)
513 {
514  return internal::TupleHelper<Args...>::template MakeTupleChecker<Ts...>(checkers...);
515 }
516 
517 template <class... Args, class T1>
518 Ptr<const AttributeAccessor>
520 {
521  return internal::TupleHelper<Args...>::template MakeTupleAccessor<T1>(a1);
522 }
523 
524 template <class... Args, class T1, class T2>
525 Ptr<const AttributeAccessor>
526 MakeTupleAccessor(T1 a1, T2 a2)
527 {
528  return internal::TupleHelper<Args...>::template MakeTupleAccessor<T1, T2>(a1, a2);
529 }
530 
531 } // namespace ns3
532 
533 #endif // TUPLE_H
Attribute helper (ATTRIBUTE_ )macros definition.
Represent the type of an attribute.
Definition: attribute.h:168
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
Checker for attribute values storing tuples.
Definition: tuple.h:155
virtual const std::vector< Ptr< const AttributeChecker > > & GetCheckers() const =0
Get the checkers for all tuple elements.
Hold objects of type std::tuple<Args...>.
Definition: tuple.h:69
bool DeserializeFromString(std::string value, Ptr< const AttributeChecker > checker) override
Definition: tuple.h:252
std::string SerializeToString(Ptr< const AttributeChecker > checker) const override
Definition: tuple.h:302
bool SetValueImpl(std::index_sequence< Is... >, const std::vector< Ptr< AttributeValue >> &values)
Set the attribute values starting from the given values.
Definition: tuple.h:236
void Set(const result_type &value)
Set the stored values.
Definition: tuple.h:318
bool GetAccessor(T &value) const
Set the given variable to the values stored by this TupleValue object.
Definition: tuple.h:333
std::tuple< Args... > value_type
Type of value stored in the TupleValue.
Definition: tuple.h:72
result_type Get() const
Get the stored values as a std::tuple.
Definition: tuple.h:311
Ptr< AttributeValue > Copy() const override
Definition: tuple.h:228
std::tuple< std::invoke_result_t< decltype(&Args::Get), Args >... > result_type
Type returned by Get or passed in Set.
Definition: tuple.h:74
value_type GetValue() const
Get the attribute values as a tuple.
Definition: tuple.h:325
value_type m_value
Tuple of attribute values.
Definition: tuple.h:130
Internal checker class templated to each AttributeChecker for each entry in the tuple.
Definition: tuple.h:351
std::string GetUnderlyingTypeInformation() const override
Definition: tuple.h:394
Ptr< AttributeValue > Create() const override
Definition: tuple.h:399
bool HasUnderlyingTypeInformation() const override
Definition: tuple.h:389
std::string GetValueTypeName() const override
Definition: tuple.h:384
const std::vector< Ptr< const AttributeChecker > > & GetCheckers() const override
Get the checkers for all tuple elements.
Definition: tuple.h:364
std::vector< Ptr< const AttributeChecker > > m_checkers
attribute checkers
Definition: tuple.h:417
TupleChecker(Ts... checkers)
Constructor.
Definition: tuple.h:359
bool Check(const AttributeValue &value) const override
Definition: tuple.h:369
bool Copy(const AttributeValue &source, AttributeValue &destination) const override
Copy the source to the destination.
Definition: tuple.h:404
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:876
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition: ptr.h:442
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:512
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:526
auto MakeTupleValue(T2 t)
Create a TupleValue object.
Definition: tuple.h:505
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:159
ns3::StringValue attribute value declarations.
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:486
static Ptr< const AttributeChecker > MakeTupleChecker(Ts... checkers)
Create a TupleChecker from AttributeCheckers associated with TupleValue elements.
Definition: tuple.h:477
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:495
static TupleValue< Args... > MakeTupleValue(const typename TupleValue< Args... >::result_type &t)
Create a TupleValue object.
Definition: tuple.h:468
Helper class defining static methods for MakeTupleChecker and MakeTupleAccessor that are called when ...
Definition: tuple.h:427
static Ptr< const AttributeChecker > MakeTupleChecker(Ts... checkers)
Create a TupleChecker from AttributeCheckers associated with TupleValue elements.
Definition: tuple.h:432
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:441
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:450