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 * 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
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
76template <class... Args>
78{
79 public:
81 typedef std::tuple<Args...> value_type;
83 typedef std::tuple<std::invoke_result_t<decltype(&Args::Get), Args>...> result_type;
84
85 TupleValue();
86
92 TupleValue(const result_type& value);
93
94 Ptr<AttributeValue> Copy() const override;
95 bool DeserializeFromString(std::string value, Ptr<const AttributeChecker> checker) override;
96 std::string SerializeToString(Ptr<const AttributeChecker> checker) const override;
97
105 result_type Get() const;
111 void Set(const result_type& value);
112
117 value_type GetValue() const;
118
127 template <typename T>
128 bool GetAccessor(T& value) const;
129
130 private:
139 template <std::size_t... Is>
140 bool SetValueImpl(std::index_sequence<Is...>, const std::vector<Ptr<AttributeValue>>& values);
141
143};
144
162template <class T1, class T2>
163auto MakeTupleValue(T2 t);
164
171{
172 public:
178 virtual const std::vector<Ptr<const AttributeChecker>>& GetCheckers() const = 0;
179};
180
191template <class... Args, class... Ts>
193
207template <class... Args, class T1>
209
224template <class... Args, class T1, class T2>
226
227} // namespace ns3
228
229/*****************************************************************************
230 * Implementation below
231 *****************************************************************************/
232
233namespace ns3
234{
235
236template <class... Args>
238 : m_value(std::make_tuple(Args()...))
239{
240}
241
242template <class... Args>
244{
245 Set(value);
246}
247
248template <class... Args>
251{
252 return Create<TupleValue<Args...>>(Get());
253}
254
255template <class... Args>
256template <std::size_t... Is>
257bool
258TupleValue<Args...>::SetValueImpl(std::index_sequence<Is...>,
259 const std::vector<Ptr<AttributeValue>>& values)
260{
261 auto valueTuple = std::make_tuple(DynamicCast<Args>(values[Is])...);
262
263 bool ok = ((std::get<Is>(valueTuple) != nullptr) && ...);
264
265 if (ok)
266 {
267 m_value = std::make_tuple(Args(*std::get<Is>(valueTuple))...);
268 }
269 return ok;
270}
271
272template <class... Args>
273bool
275{
276 auto tupleChecker = DynamicCast<const TupleChecker>(checker);
277 if (!tupleChecker)
278 {
279 return false;
280 }
281
282 auto count = tupleChecker->GetCheckers().size();
283 if (count != sizeof...(Args))
284 {
285 return false;
286 }
287
288 if (value.empty() || value.front() != '{' || value.back() != '}')
289 {
290 return false;
291 }
292
293 value.erase(value.begin());
294 value.pop_back();
295 std::replace(value.data(), value.data() + value.size(), ',', ' ');
296
297 std::istringstream iss(value);
298 std::vector<Ptr<AttributeValue>> values;
299 std::size_t i = 0;
300
301 while (iss >> value)
302 {
303 if (i >= count)
304 {
305 return false;
306 }
307 values.push_back(tupleChecker->GetCheckers().at(i++)->CreateValidValue(StringValue(value)));
308 if (!values.back())
309 {
310 return false;
311 }
312 }
313
314 if (i != count)
315 {
316 return false;
317 }
318
319 return SetValueImpl(std::index_sequence_for<Args...>{}, values);
320}
321
322template <class... Args>
323std::string
325{
326 std::ostringstream oss;
327 oss << "{" << Get() << "}";
328 return oss.str();
329}
330
331template <class... Args>
332typename TupleValue<Args...>::result_type
334{
335 return std::apply([](Args... values) { return std::make_tuple(values.Get()...); }, m_value);
336}
337
338template <class... Args>
339void
341{
342 m_value = std::apply([](auto&&... args) { return std::make_tuple(Args(args)...); }, value);
343}
344
345template <class... Args>
346typename TupleValue<Args...>::value_type
348{
349 return m_value;
350}
351
352template <class... Args>
353template <typename T>
354bool
356{
357 value = T(Get());
358 return true;
359}
360
361// This internal class defines templated TupleChecker class that is instantiated
362// in MakeTupleChecker. The non-templated base ns3::TupleChecker is returned in that
363// function. This is the same pattern as ObjectPtrContainer.
364namespace internal
365{
366
373template <class... Args>
375{
376 public:
382 template <class... Ts>
383 TupleChecker(Ts... checkers)
384 : m_checkers{checkers...}
385 {
386 }
387
388 const std::vector<Ptr<const AttributeChecker>>& GetCheckers() const override
389 {
390 return m_checkers;
391 }
392
393 bool Check(const AttributeValue& value) const override
394 {
395 const auto v = dynamic_cast<const TupleValue<Args...>*>(&value);
396 if (v == nullptr)
397 {
398 return false;
399 }
400 return std::apply(
401 [this](Args... values) {
402 std::size_t n{0};
403 return (m_checkers[n++]->Check(values) && ...);
404 },
405 v->GetValue());
406 }
407
408 std::string GetValueTypeName() const override
409 {
410 return "ns3::TupleValue";
411 }
412
413 bool HasUnderlyingTypeInformation() const override
414 {
415 return false;
416 }
417
418 std::string GetUnderlyingTypeInformation() const override
419 {
420 return "";
421 }
422
424 {
425 return ns3::Create<TupleValue<Args...>>();
426 }
427
428 bool Copy(const AttributeValue& source, AttributeValue& destination) const override
429 {
430 const auto src = dynamic_cast<const TupleValue<Args...>*>(&source);
431 auto dst = dynamic_cast<TupleValue<Args...>*>(&destination);
432 if (src == nullptr || dst == nullptr)
433 {
434 return false;
435 }
436 *dst = *src;
437 return true;
438 }
439
440 private:
441 std::vector<Ptr<const AttributeChecker>> m_checkers;
442};
443
451template <class... Args>
453{
457 template <class... Ts>
459 {
460 return Create<internal::TupleChecker<Args...>>(checkers...);
461 }
462
466 template <class T1>
468 {
469 return MakeAccessorHelper<TupleValue<Args...>>(a1);
470 }
471
475 template <class T1, class T2>
477 {
478 return MakeAccessorHelper<TupleValue<Args...>>(a1, a2);
479 }
480};
481
490template <class... Args>
491struct TupleHelper<std::tuple<Args...>>
492{
497 {
498 return TupleValue<Args...>(t);
499 }
500
504 template <class... Ts>
506 {
507 return Create<internal::TupleChecker<Args...>>(checkers...);
508 }
509
513 template <class T1>
515 {
516 return MakeAccessorHelper<TupleValue<Args...>>(a1);
517 }
518
522 template <class T1, class T2>
524 {
525 return MakeAccessorHelper<TupleValue<Args...>>(a1, a2);
526 }
527};
528
529} // namespace internal
530
531template <class T1, class T2>
532auto
534{
536}
537
538template <class... Args, class... Ts>
539Ptr<const AttributeChecker>
540MakeTupleChecker(Ts... checkers)
541{
542 return internal::TupleHelper<Args...>::template MakeTupleChecker<Ts...>(checkers...);
543}
544
545template <class... Args, class T1>
546Ptr<const AttributeAccessor>
548{
549 return internal::TupleHelper<Args...>::template MakeTupleAccessor<T1>(a1);
550}
551
552template <class... Args, class T1, class T2>
553Ptr<const AttributeAccessor>
554MakeTupleAccessor(T1 a1, T2 a2)
555{
556 return internal::TupleHelper<Args...>::template MakeTupleAccessor<T1, T2>(a1, a2);
557}
558
559} // namespace ns3
560
561#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:171
virtual const std::vector< Ptr< const AttributeChecker > > & GetCheckers() const =0
Get the checkers for all tuple elements.
AttributeValue implementation for Tuple.
Definition: tuple.h:78
bool DeserializeFromString(std::string value, Ptr< const AttributeChecker > checker) override
Definition: tuple.h:274
std::string SerializeToString(Ptr< const AttributeChecker > checker) const override
Definition: tuple.h:324
void Set(const result_type &value)
Set the stored values.
Definition: tuple.h:340
bool GetAccessor(T &value) const
Set the given variable to the values stored by this TupleValue object.
Definition: tuple.h:355
std::tuple< Args... > value_type
Type of value stored in the TupleValue.
Definition: tuple.h:81
result_type Get() const
Get the stored values as a std::tuple.
Definition: tuple.h:333
Ptr< AttributeValue > Copy() const override
Definition: tuple.h:250
bool SetValueImpl(std::index_sequence< Is... >, const std::vector< Ptr< AttributeValue > > &values)
Set the attribute values starting from the given values.
Definition: tuple.h:258
std::tuple< std::invoke_result_t< decltype(&Args::Get), Args >... > result_type
Type returned by Get or passed in Set.
Definition: tuple.h:83
value_type GetValue() const
Get the attribute values as a tuple.
Definition: tuple.h:347
value_type m_value
Tuple of attribute values.
Definition: tuple.h:142
Internal checker class templated to each AttributeChecker for each entry in the tuple.
Definition: tuple.h:375
std::string GetUnderlyingTypeInformation() const override
Definition: tuple.h:418
bool HasUnderlyingTypeInformation() const override
Definition: tuple.h:413
std::string GetValueTypeName() const override
Definition: tuple.h:408
std::vector< Ptr< const AttributeChecker > > m_checkers
attribute checkers
Definition: tuple.h:441
TupleChecker(Ts... checkers)
Constructor.
Definition: tuple.h:383
const std::vector< Ptr< const AttributeChecker > > & GetCheckers() const override
Get the checkers for all tuple elements.
Definition: tuple.h:388
bool Check(const AttributeValue &value) const override
Definition: tuple.h:393
Ptr< AttributeValue > Create() const override
Definition: tuple.h:423
bool Copy(const AttributeValue &source, AttributeValue &destination) const override
Copy the source to the destination.
Definition: tuple.h:428
Ptr< const AttributeChecker > MakeTupleChecker(Ts... checkers)
Create a TupleChecker from AttributeCheckers associated with TupleValue elements.
Definition: tuple.h:540
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:547
auto MakeTupleValue(T2 t)
Create a TupleValue object.
Definition: tuple.h:533
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:442
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:159
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:505
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:514
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:523
static TupleValue< Args... > MakeTupleValue(const typename TupleValue< Args... >::result_type &t)
Create a TupleValue object.
Definition: tuple.h:496
Helper class defining static methods for MakeTupleChecker and MakeTupleAccessor that are called when ...
Definition: tuple.h:453
static Ptr< const AttributeChecker > MakeTupleChecker(Ts... checkers)
Create a TupleChecker from AttributeCheckers associated with TupleValue elements.
Definition: tuple.h:458
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:467
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:476