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 <ns3/attribute-helper.h>
24#include <ns3/string.h>
25
26#include <algorithm>
27#include <sstream>
28#include <tuple>
29#include <type_traits>
30#include <utility>
31
32namespace ns3
33{
34
47template <class... Args>
48std::ostream&
49operator<<(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
67template <class... Args>
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
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
148template <class T1, class T2>
149auto MakeTupleValue(T2 t);
150
155{
156 public:
162 virtual const std::vector<Ptr<const AttributeChecker>>& GetCheckers() const = 0;
163};
164
173template <class... Args, class... Ts>
175
187template <class... Args, class T1>
189
202template <class... Args, class T1, class T2>
204
205} // namespace ns3
206
207/*****************************************************************************
208 * Implementation below
209 *****************************************************************************/
210
211namespace ns3
212{
213
214template <class... Args>
216 : m_value(std::make_tuple(Args()...))
217{
218}
219
220template <class... Args>
222{
223 Set(value);
224}
225
226template <class... Args>
229{
230 return Create<TupleValue<Args...>>(Get());
231}
232
233template <class... Args>
234template <std::size_t... Is>
235bool
236TupleValue<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
250template <class... Args>
251bool
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
300template <class... Args>
301std::string
303{
304 std::ostringstream oss;
305 oss << "{" << Get() << "}";
306 return oss.str();
307}
308
309template <class... Args>
310typename TupleValue<Args...>::result_type
312{
313 return std::apply([](Args... values) { return std::make_tuple(values.Get()...); }, m_value);
314}
315
316template <class... Args>
317void
319{
320 m_value = std::apply([](auto&&... args) { return std::make_tuple(Args(args)...); }, value);
321}
322
323template <class... Args>
324typename TupleValue<Args...>::value_type
326{
327 return m_value;
328}
329
330template <class... Args>
331template <typename T>
332bool
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.
342namespace internal
343{
344
349template <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 TupleValue<Args...>* 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
400 {
401 return ns3::Create<TupleValue<Args...>>();
402 }
403
404 bool Copy(const AttributeValue& source, AttributeValue& destination) const override
405 {
406 const TupleValue<Args...>* src = dynamic_cast<const TupleValue<Args...>*>(&source);
407 TupleValue<Args...>* 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
425template <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
462template <class... Args>
463struct TupleHelper<std::tuple<Args...>>
464{
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
503template <class T1, class T2>
504auto
506{
508}
509
510template <class... Args, class... Ts>
511Ptr<const AttributeChecker>
512MakeTupleChecker(Ts... checkers)
513{
514 return internal::TupleHelper<Args...>::template MakeTupleChecker<Ts...>(checkers...);
515}
516
517template <class... Args, class T1>
518Ptr<const AttributeAccessor>
520{
521 return internal::TupleHelper<Args...>::template MakeTupleAccessor<T1>(a1);
522}
523
524template <class... Args, class T1, class T2>
525Ptr<const AttributeAccessor>
526MakeTupleAccessor(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
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:78
Hold variables of type string.
Definition: string.h:42
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
result_type Get() const
Get the stored values as a std::tuple.
Definition: tuple.h:311
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
value_type m_value
Tuple of attribute values.
Definition: tuple.h:130
Ptr< AttributeValue > Copy() const override
Definition: tuple.h:228
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
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
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
bool HasUnderlyingTypeInformation() const override
Definition: tuple.h:389
std::string GetValueTypeName() const override
Definition: tuple.h:384
std::vector< Ptr< const AttributeChecker > > m_checkers
attribute checkers
Definition: tuple.h:417
TupleChecker(Ts... checkers)
Constructor.
Definition: tuple.h:359
const std::vector< Ptr< const AttributeChecker > > & GetCheckers() const override
Get the checkers for all tuple elements.
Definition: tuple.h:364
bool Check(const AttributeValue &value) const override
Definition: tuple.h:369
Ptr< AttributeValue > Create() const override
Definition: tuple.h:399
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:877
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition: ptr.h:481
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
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:129
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
value
Definition: second.py:41
STL namespace.
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)
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 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