A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
tuple.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2021 Universita' degli Studi di Napoli Federico II
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Stefano Avallone <stavallo@unina.it>
7 */
8
9#ifndef TUPLE_H
10#define TUPLE_H
11
12#include "attribute-helper.h"
13#include "string.h"
14
15#include <algorithm>
16#include <sstream>
17#include <tuple>
18#include <type_traits>
19#include <utility>
20
21namespace ns3
22{
23
24/**
25 * @brief Stream insertion operator.
26 * See https://en.cppreference.com/w/cpp/utility/apply
27 *
28 * Prints tuple values separated by a comma. E.g., if the tuple contains
29 * v1, v2 and v3, then "v1, v2, v3" will be added to the stream.
30 *
31 * @tparam Args \deduced Tuple arguments
32 * @param os the output stream
33 * @param t the tuple
34 * @returns a reference to the stream
35 */
36template <class... Args>
37std::ostream&
38operator<<(std::ostream& os, const std::tuple<Args...>& t)
39{
40 std::apply(
41 [&os](auto&&... args) {
42 std::size_t n{0};
43 ((os << args << (++n != sizeof...(Args) ? ", " : "")), ...);
44 },
45 t);
46 return os;
47}
48
49/**
50 * @ingroup attributes
51 * @defgroup attribute_Tuple Tuple Attribute
52 * AttributeValue implementation for Tuple
53 */
54
55/**
56 * @ingroup attribute_Tuple
57 *
58 * AttributeValue implementation for Tuple.
59 *
60 * Hold objects of type std::tuple<Args...>.
61 * @tparam Args \explicit The list of AttributeValues to be held by this TupleValue
62 *
63 * @see AttributeValue
64 */
65template <class... Args>
67{
68 public:
69 /** Type of value stored in the TupleValue. */
70 typedef std::tuple<Args...> value_type;
71 /** Type returned by Get or passed in Set. */
72 typedef std::tuple<std::invoke_result_t<decltype(&Args::Get), Args>...> result_type;
73
74 TupleValue();
75
76 /**
77 * Construct this TupleValue from a std::tuple
78 *
79 * @param [in] value Value with which to construct.
80 */
81 TupleValue(const result_type& value);
82
83 Ptr<AttributeValue> Copy() const override;
84 bool DeserializeFromString(std::string value, Ptr<const AttributeChecker> checker) override;
85 std::string SerializeToString(Ptr<const AttributeChecker> checker) const override;
86
87 /**
88 * Get the stored values as a std::tuple.
89 *
90 * This differs from the actual value stored in the object which is
91 * a tuple of Ptr<AV> where AV is a class derived from AttributeValue.
92 * @return stored values as a std::tuple
93 */
94 result_type Get() const;
95 /**
96 * Set the stored values.
97 *
98 * @param value The stored value
99 */
100 void Set(const result_type& value);
101
102 /**
103 * Get the attribute values as a tuple.
104 * @return the attribute values as a tuple
105 */
106 value_type GetValue() const;
107
108 /**
109 * Set the given variable to the values stored by this TupleValue object.
110 *
111 * @tparam T \deduced the type of the given variable (normally, the argument type
112 * of a set method or the type of a data member)
113 * @param [out] value The stored value
114 * @return true if the given variable was set
115 */
116 template <typename T>
117 bool GetAccessor(T& value) const;
118
119 private:
120 /**
121 * Set the attribute values starting from the given values.
122 * Used by DeserializeFromString method.
123 *
124 * @tparam Is \deduced index sequence
125 * @param values the given attribute values
126 * @return true if the attribute values of this object were set
127 */
128 template <std::size_t... Is>
129 bool SetValueImpl(std::index_sequence<Is...>, const std::vector<Ptr<AttributeValue>>& values);
130
131 value_type m_value; //!< Tuple of attribute values
132};
133
134/**
135 * @ingroup attribute_Tuple
136 *
137 * Create a TupleValue object. Enable to write code like this snippet:
138 *
139 * @code
140 * typedef std::tuple<uint16_t, double> Tuple;
141 * typedef std::tuple<UintegerValue, DoubleValue> Pack;
142 *
143 * TupleValue<UintegerValue, DoubleValue> t = MakeTupleValue<Pack> (Tuple {10, 1.5});
144 * @endcode
145 *
146 * @tparam T1 \explicit A std::tuple of the AttributeValue types included in TupleValue
147 * @tparam T2 \deduced A std::tuple of the type of elements stored by TupleValue
148 * @param t the tuple of elements stored by TupleValue
149 * @return a TupleValue object
150 */
151template <class T1, class T2>
152auto MakeTupleValue(T2 t);
153
154/**
155 * @ingroup attribute_Tuple
156 *
157 * Checker for attribute values storing tuples.
158 */
160{
161 public:
162 /**
163 * Get the checkers for all tuple elements.
164 *
165 * @return the checkers for all tuple elements
166 */
167 virtual const std::vector<Ptr<const AttributeChecker>>& GetCheckers() const = 0;
168};
169
170/**
171 * @ingroup attribute_Tuple
172 *
173 * Create a TupleChecker from AttributeCheckers associated with TupleValue elements.
174 *
175 * @tparam Args \explicit Attribute value types
176 * @tparam Ts \deduced Attribute checker types
177 * @param checkers attribute checkers
178 * @return Pointer to TupleChecker instance.
179 */
180template <class... Args, class... Ts>
182
183/**
184 * @ingroup attribute_Tuple
185 *
186 * Create an AttributeAccessor for a class data member of type tuple,
187 * or a lone class get functor or set method.
188 *
189 * @tparam Args \explicit Attribute value types
190 * @tparam T1 \deduced The type of the class data member,
191 * or the type of the class get functor or set method.
192 * @param a1 The address of the data member,
193 * or the get or set method.
194 * @return the AttributeAccessor
195 */
196template <class... Args, class T1>
198
199/**
200 * @ingroup attribute_Tuple
201 *
202 * Create an AttributeAccessor using a pair of get functor
203 * and set methods from a class.
204 *
205 * @tparam Args \explicit Attribute value types
206 * @tparam T1 \deduced The type of the class data member,
207 * or the type of the class get functor or set method.
208 * @tparam T2 \deduced The type of the getter class functor method.
209 * @param a2 The address of the class method to set the attribute.
210 * @param a1 The address of the data member, or the get or set method.
211 * @return the AttributeAccessor
212 */
213template <class... Args, class T1, class T2>
215
216} // namespace ns3
217
218/*****************************************************************************
219 * Implementation below
220 *****************************************************************************/
221
222namespace ns3
223{
224
225template <class... Args>
227 : m_value(std::make_tuple(Args()...))
228{
229}
230
231template <class... Args>
233{
234 Set(value);
235}
236
237template <class... Args>
240{
241 return Create<TupleValue<Args...>>(Get());
242}
243
244template <class... Args>
245template <std::size_t... Is>
246bool
247TupleValue<Args...>::SetValueImpl(std::index_sequence<Is...>,
248 const std::vector<Ptr<AttributeValue>>& values)
249{
250 auto valueTuple = std::make_tuple(DynamicCast<Args>(values[Is])...);
251
252 bool ok = ((std::get<Is>(valueTuple) != nullptr) && ...);
253
254 if (ok)
255 {
256 m_value = std::make_tuple(Args(*std::get<Is>(valueTuple))...);
257 }
258 return ok;
259}
260
261template <class... Args>
262bool
264{
265 auto tupleChecker = DynamicCast<const TupleChecker>(checker);
266 if (!tupleChecker)
267 {
268 return false;
269 }
270
271 auto count = tupleChecker->GetCheckers().size();
272 if (count != sizeof...(Args))
273 {
274 return false;
275 }
276
277 if (value.empty() || value.front() != '{' || value.back() != '}')
278 {
279 return false;
280 }
281
282 value.erase(value.begin());
283 value.pop_back();
284
285 std::istringstream iss(value);
286 std::vector<Ptr<AttributeValue>> values;
287 std::size_t i = 0;
288
289 for (std::string elem; std::getline(iss, elem, ',');)
290 {
291 // remove leading whitespaces
292 std::istringstream tmp{elem};
293 std::getline(tmp >> std::ws, value);
294
295 if (i >= count)
296 {
297 return false;
298 }
299 values.push_back(tupleChecker->GetCheckers().at(i++)->CreateValidValue(StringValue(value)));
300 if (!values.back())
301 {
302 return false;
303 }
304 }
305
306 if (i != count)
307 {
308 return false;
309 }
310
311 return SetValueImpl(std::index_sequence_for<Args...>{}, values);
312}
313
314template <class... Args>
315std::string
317{
318 std::ostringstream oss;
319 oss << "{" << Get() << "}";
320 return oss.str();
321}
322
323template <class... Args>
324typename TupleValue<Args...>::result_type
326{
327 return std::apply([](Args... values) { return std::make_tuple(values.Get()...); }, m_value);
328}
329
330template <class... Args>
331void
333{
334 m_value = std::apply([](auto&&... args) { return std::make_tuple(Args(args)...); }, value);
335}
336
337template <class... Args>
338typename TupleValue<Args...>::value_type
340{
341 return m_value;
342}
343
344template <class... Args>
345template <typename T>
346bool
348{
349 value = T(Get());
350 return true;
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.
356namespace internal
357{
358
359/**
360 * @ingroup attribute_Tuple
361 *
362 * Internal checker class templated to each AttributeChecker
363 * for each entry in the tuple.
364 */
365template <class... Args>
367{
368 public:
369 /**
370 * Constructor.
371 * @tparam Ts \deduced the type of the attribute checkers
372 * @param checkers the attribute checkers for individual elements of the tuple
373 */
374 template <class... Ts>
375 TupleChecker(Ts... checkers)
376 : m_checkers{checkers...}
377 {
378 }
379
380 const std::vector<Ptr<const AttributeChecker>>& GetCheckers() const override
381 {
382 return m_checkers;
383 }
384
385 bool Check(const AttributeValue& value) const override
386 {
387 const auto v = dynamic_cast<const TupleValue<Args...>*>(&value);
388 if (v == nullptr)
389 {
390 return false;
391 }
392 return std::apply(
393 [this](Args... values) {
394 std::size_t n{0};
395 return (m_checkers[n++]->Check(values) && ...);
396 },
397 v->GetValue());
398 }
399
400 std::string GetValueTypeName() const override
401 {
402 return "ns3::TupleValue";
403 }
404
405 bool HasUnderlyingTypeInformation() const override
406 {
407 return false;
408 }
409
410 std::string GetUnderlyingTypeInformation() const override
411 {
412 return "";
413 }
414
416 {
417 return ns3::Create<TupleValue<Args...>>();
418 }
419
420 bool Copy(const AttributeValue& source, AttributeValue& destination) const override
421 {
422 const auto src = dynamic_cast<const TupleValue<Args...>*>(&source);
423 auto dst = dynamic_cast<TupleValue<Args...>*>(&destination);
424 if (src == nullptr || dst == nullptr)
425 {
426 return false;
427 }
428 *dst = *src;
429 return true;
430 }
431
432 private:
433 std::vector<Ptr<const AttributeChecker>> m_checkers; //!< attribute checkers
434};
435
436/**
437 * @ingroup attribute_Tuple
438 *
439 * Helper class defining static methods for MakeTupleChecker and MakeTupleAccessor
440 * that are called when user specifies the list of AttributeValue types included
441 * in a TupleValue type.
442 */
443template <class... Args>
445{
446 /**
447 * @copydoc ns3::MakeTupleChecker
448 */
449 template <class... Ts>
451 {
452 return Create<internal::TupleChecker<Args...>>(checkers...);
453 }
454
455 /**
456 * @copydoc ns3::MakeTupleAccessor(T1)
457 */
458 template <class T1>
460 {
461 return MakeAccessorHelper<TupleValue<Args...>>(a1);
462 }
463
464 /**
465 * @copydoc ns3::MakeTupleAccessor(T1,T2)
466 */
467 template <class T1, class T2>
469 {
470 return MakeAccessorHelper<TupleValue<Args...>>(a1, a2);
471 }
472};
473
474/**
475 * @ingroup attribute_Tuple
476 *
477 * Helper class defining static methods for MakeTupleValue, MakeTupleChecker and
478 * MakeTupleAccessor that are called when user provides a std::tuple of the
479 * AttributeValue types included in a TupleValue type.
480 * This struct is a partial specialization of struct TupleHelper.
481 */
482template <class... Args>
483struct TupleHelper<std::tuple<Args...>>
484{
485 /**
486 * @copydoc ns3::MakeTupleValue
487 */
489 {
490 return TupleValue<Args...>(t);
491 }
492
493 /**
494 * @copydoc ns3::MakeTupleChecker
495 */
496 template <class... Ts>
498 {
499 return Create<internal::TupleChecker<Args...>>(checkers...);
500 }
501
502 /**
503 * @copydoc ns3::MakeTupleAccessor(T1)
504 */
505 template <class T1>
507 {
508 return MakeAccessorHelper<TupleValue<Args...>>(a1);
509 }
510
511 /**
512 * @copydoc ns3::MakeTupleAccessor(T1,T2)
513 */
514 template <class T1, class T2>
516 {
517 return MakeAccessorHelper<TupleValue<Args...>>(a1, a2);
518 }
519};
520
521} // namespace internal
522
523template <class T1, class T2>
524auto
529
530template <class... Args, class... Ts>
531Ptr<const AttributeChecker>
532MakeTupleChecker(Ts... checkers)
533{
534 return internal::TupleHelper<Args...>::template MakeTupleChecker<Ts...>(checkers...);
535}
536
537template <class... Args, class T1>
538Ptr<const AttributeAccessor>
540{
541 return internal::TupleHelper<Args...>::template MakeTupleAccessor<T1>(a1);
542}
543
544template <class... Args, class T1, class T2>
545Ptr<const AttributeAccessor>
546MakeTupleAccessor(T1 a1, T2 a2)
547{
548 return internal::TupleHelper<Args...>::template MakeTupleAccessor<T1, T2>(a1, a2);
549}
550
551} // namespace ns3
552
553#endif // TUPLE_H
Attribute helper (ATTRIBUTE_ )macros definition.
Represent the type of an attribute.
Definition attribute.h:157
Hold a value for an Attribute.
Definition attribute.h:59
Smart pointer class similar to boost::intrusive_ptr.
Hold variables of type string.
Definition string.h:45
Checker for attribute values storing tuples.
Definition tuple.h:160
virtual const std::vector< Ptr< const AttributeChecker > > & GetCheckers() const =0
Get the checkers for all tuple elements.
AttributeValue implementation for Tuple.
Definition tuple.h:67
bool DeserializeFromString(std::string value, Ptr< const AttributeChecker > checker) override
Definition tuple.h:263
std::string SerializeToString(Ptr< const AttributeChecker > checker) const override
Definition tuple.h:316
void Set(const result_type &value)
Set the stored values.
Definition tuple.h:332
bool GetAccessor(T &value) const
Set the given variable to the values stored by this TupleValue object.
Definition tuple.h:347
std::tuple< Args... > value_type
Type of value stored in the TupleValue.
Definition tuple.h:70
result_type Get() const
Get the stored values as a std::tuple.
Definition tuple.h:325
Ptr< AttributeValue > Copy() const override
Definition tuple.h:239
bool SetValueImpl(std::index_sequence< Is... >, const std::vector< Ptr< AttributeValue > > &values)
Set the attribute values starting from the given values.
Definition tuple.h:247
std::tuple< std::invoke_result_t< decltype(&Args::Get), Args >... > result_type
Type returned by Get or passed in Set.
Definition tuple.h:72
value_type GetValue() const
Get the attribute values as a tuple.
Definition tuple.h:339
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:367
std::string GetUnderlyingTypeInformation() const override
Definition tuple.h:410
bool HasUnderlyingTypeInformation() const override
Definition tuple.h:405
std::string GetValueTypeName() const override
Definition tuple.h:400
std::vector< Ptr< const AttributeChecker > > m_checkers
attribute checkers
Definition tuple.h:433
TupleChecker(Ts... checkers)
Constructor.
Definition tuple.h:375
const std::vector< Ptr< const AttributeChecker > > & GetCheckers() const override
Get the checkers for all tuple elements.
Definition tuple.h:380
bool Check(const AttributeValue &value) const override
Definition tuple.h:385
Ptr< AttributeValue > Create() const override
Definition tuple.h:415
bool Copy(const AttributeValue &source, AttributeValue &destination) const override
Copy the source to the destination.
Definition tuple.h:420
Ptr< const AttributeChecker > MakeTupleChecker(Ts... checkers)
Create a TupleChecker from AttributeCheckers associated with TupleValue elements.
Definition tuple.h:532
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:539
auto MakeTupleValue(T2 t)
Create a TupleValue object.
Definition tuple.h:525
Ptr< const AttributeAccessor > MakeAccessorHelper(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition angles.cc:148
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580
STL namespace.
ns3::StringValue attribute value declarations.
static Ptr< const AttributeChecker > MakeTupleChecker(Ts... checkers)
Create a TupleChecker from AttributeCheckers associated with TupleValue elements.
Definition tuple.h:497
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:506
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:515
static TupleValue< Args... > MakeTupleValue(const typename TupleValue< Args... >::result_type &t)
Create a TupleValue object.
Definition tuple.h:488
Helper class defining static methods for MakeTupleChecker and MakeTupleAccessor that are called when ...
Definition tuple.h:445
static Ptr< const AttributeChecker > MakeTupleChecker(Ts... checkers)
Create a TupleChecker from AttributeCheckers associated with TupleValue elements.
Definition tuple.h:450
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:459
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:468