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
33namespace ns3 {
34
47template <class... Args>
48std::ostream &
49operator << (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
68template <class... Args>
70{
71public:
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
119private:
128 template <std::size_t... Is>
129 bool SetValueImpl (std::index_sequence<Is...>, const std::vector<Ptr<AttributeValue>>& values);
130
132};
133
149template <class T1, class T2>
150auto MakeTupleValue (T2 t);
151
152
157{
158public:
164 virtual const std::vector<Ptr<const AttributeChecker>>& GetCheckers (void) const = 0;
165};
166
167
176template <class... Args, class... Ts>
178
179
191template <class... Args, class T1>
193
206template <class... Args, class T1, class T2>
208
209
210} // namespace ns3
211
212/*****************************************************************************
213 * Implementation below
214 *****************************************************************************/
215
216namespace ns3 {
217
218template <class... Args>
220 : m_value (std::make_tuple (Args ()...))
221{
222}
223
224template <class... Args>
226{
227 Set (value);
228}
229
230template <class... Args>
233{
234 return Create <TupleValue <Args...>> (Get ());
235}
236
237template <class... Args>
238template <std::size_t... Is>
239bool
240TupleValue<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
253template <class... Args>
254bool
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
303template <class... Args>
304std::string
306{
307 std::ostringstream oss;
308 oss << "{" << Get () << "}";
309 return oss.str ();
310}
311
312template <class... Args>
313typename 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
323template <class... Args>
324void
326{
327 m_value = std::apply ([](auto&&... args)
328 {
329 return std::make_tuple (Args (args)...);
330 },
331 value);
332}
333
334template <class... Args>
335typename TupleValue<Args...>::value_type
337{
338 return m_value;
339}
340
341template <class... Args>
342template <typename T>
343bool
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.
356namespace internal {
357
362template <class... Args>
364{
365public:
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
422private:
423 std::vector<Ptr<const AttributeChecker>> m_checkers;
424};
425
431template <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
466template <class... Args>
467struct TupleHelper<std::tuple<Args...>>
468{
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
506template <class T1, class T2>
507auto MakeTupleValue (T2 t)
508{
510}
511
512template <class... Args, class... Ts>
514{
515 return internal::TupleHelper<Args...>::template MakeTupleChecker<Ts...> (checkers...);
516}
517
518template <class... Args, class T1>
520{
521 return internal::TupleHelper<Args...>::template MakeTupleAccessor<T1> (a1);
522}
523
524template <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
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
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
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
bool HasUnderlyingTypeInformation(void) const override
Definition: tuple.h:398
std::vector< Ptr< const AttributeChecker > > m_checkers
attribute checkers
Definition: tuple.h:423
TupleChecker(Ts... checkers)
Constructor.
Definition: tuple.h:372
Ptr< AttributeValue > Create(void) const override
Definition: tuple.h:406
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
const std::vector< Ptr< const AttributeChecker > > & GetCheckers(void) const override
Get the checkers for all tuple elements.
Definition: tuple.h:376
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
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:139
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
STL namespace.
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)
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 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