A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
pair.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018 Caliola Engineering, LLC.
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Jared Dulmage <jared.dulmage@caliola.com>
7 */
8
9#ifndef PAIR_H
10#define PAIR_H
11
12#include "attribute-helper.h"
13#include "string.h"
14
15#include <sstream>
16#include <type_traits>
17#include <typeinfo> // typeid
18#include <utility>
19
20namespace ns3
21{
22
23/**
24 * Output streamer for a std::pair.
25 * \tparam A \deduced Type of the `pair.first`.
26 * \tparam B \deduced Type of the `pair.second`.
27 * \param [in,out] os The output stream.
28 * \param [in] p The pair.
29 * \returns The output stream.
30 */
31template <class A, class B>
32std::ostream&
33operator<<(std::ostream& os, const std::pair<A, B>& p)
34{
35 os << "(" << p.first << "," << p.second << ")";
36 return os;
37}
38
39/**
40 * \ingroup attributes
41 * \defgroup attribute_Pair Pair Attribute
42 * AttributeValue implementation for Pair
43 */
44
45/**
46 * \ingroup attribute_Pair
47 * AttributeValue implementation for Pair.
48 * Hold objects of type std::pair<A, B>.
49 *
50 * \see AttributeValue
51 */
52template <class A, class B>
54{
55 public:
56 /** Type of value stored in the PairValue. */
57 typedef std::pair<Ptr<A>, Ptr<B>> value_type;
58 /** Type of abscissa (first entry of pair). */
59 typedef typename std::invoke_result_t<decltype(&A::Get), A> first_type;
60 /** Type of ordinal (second entry of pair). */
61 typedef typename std::invoke_result_t<decltype(&B::Get), B> second_type;
62 /** Type returned by Get or passed in Set. */
63 typedef typename std::pair<first_type, second_type> result_type;
64
66 : m_value(std::make_pair(Create<A>(), Create<B>())){};
67
68 /**
69 * Construct this PairValue from a std::pair
70 *
71 * \param [in] value Value with which to construct.
72 */
73 PairValue(const result_type& value)
74 {
75 Set(value);
76 }; // "import" constructor
77
78 // Inherited
79 Ptr<AttributeValue> Copy() const override;
80 bool DeserializeFromString(std::string value, Ptr<const AttributeChecker> checker) override;
81 std::string SerializeToString(Ptr<const AttributeChecker> checker) const override;
82
83 /**
84 * Get the stored value as a std::pair.
85 *
86 * This differs from the actual value stored in the object which is
87 * a pair of Ptr<AV> where AV is a class derived from AttributeValue.
88 * \return stored value as std::pair<A, B>.
89 */
90 result_type Get() const;
91 /**
92 * Set the value.
93 * \param [in] value The value to adopt.
94 */
95 void Set(const result_type& value);
96
97 /**
98 * Access the Pair value as type \p T.
99 * \tparam T \explicit The type to cast to.
100 * \param [out] value The Pair value, as type \p T.
101 * \returns true.
102 */
103 template <typename T>
104 bool GetAccessor(T& value) const;
105
106 private:
107 value_type m_value; //!< The stored Pair instance.
108};
109
110/**
111 * \ingroup attribute_Pair
112 * AttributeChecker implementation for PairValue.
113 * \see AttributeChecker
114 */
116{
117 public:
118 /** Type holding an AttributeChecker for each member of a pair. */
119 typedef std::pair<Ptr<const AttributeChecker>, Ptr<const AttributeChecker>> checker_pair_type;
120
121 /**
122 * Set the individual AttributeChecker for each pair entry.
123 *
124 * \param[in] firstchecker AttributeChecker for abscissa.
125 * \param[in] secondchecker AttributeChecker for ordinate.
126 */
127 virtual void SetCheckers(Ptr<const AttributeChecker> firstchecker,
128 Ptr<const AttributeChecker> secondchecker) = 0;
129
130 /**
131 * Get the pair of checkers for each pair entry.
132 *
133 * \return std::pair with AttributeChecker for each of abscissa and ordinate.
134 */
135 virtual checker_pair_type GetCheckers() const = 0;
136};
137
138/**
139 * \ingroup attribute_Pair
140 *
141 * Make a PairChecker from a PairValue.
142 *
143 * This function returns a Pointer to a non-const instance to
144 * allow subsequent setting of the underlying AttributeCheckers.
145 * \param[in] value PairValue from which to derive abscissa and ordinate types.
146 * \return Pointer to PairChecker instance.
147 */
148template <class A, class B>
150
151/**
152 * \ingroup attribute_Pair
153 *
154 * Make a PairChecker from abscissa and ordinate AttributeCheckers.
155 *
156 * This function returns a Pointer to a const instance since both
157 * underlying AttributeCheckers are set.
158 *
159 * \param[in] firstchecker AttributeChecker for abscissa.
160 * \param[in] secondchecker AttributeChecker for ordinate.
161 * \return Pointer to PairChecker instance.
162 */
163template <class A, class B>
165 Ptr<const AttributeChecker> secondchecker);
166
167/**
168 * \ingroup attribute_Pair
169 *
170 * Make a PairChecker without abscissa and ordinate AttributeCheckers.
171 *
172 * \return Pointer to PairChecker instance.
173 */
174template <class A, class B>
176
177/**
178 * \ingroup attribute_Pair
179 *
180 * Create an AttributeAccessor for std::pair<>.
181 * \tparam A \explicit The type of pair.first.
182 * \tparam B \explicit The type of pair.second.
183 * \tparam T1 \deduced The argument pair type.
184 * \param [in] a1 The std::pair to be accessed.
185 * \returns The AttributeAccessor.
186 */
187template <typename A, typename B, typename T1>
189
190} // namespace ns3
191
192/*****************************************************************************
193 * Implementation below
194 *****************************************************************************/
195
196namespace ns3
197{
198
199// This internal class defines templated PairChecker class that is instantiated
200// in MakePairChecker. The non-templated base ns3::PairChecker is returned in that
201// function. This is the same pattern as ObjectPtrContainer.
202namespace internal
203{
204
205/**
206 * \ingroup attribute_Pair
207 *
208 * Internal checker class templated to each AttributeChecker
209 * for each entry in the pair.
210 */
211template <class A, class B>
213{
214 public:
215 /** Default c'tor. */
216 PairChecker();
217 /**
218 * Construct from a pair of AttributeChecker's.
219 * \param firstchecker The AttributeChecker for first.
220 * \param secondchecker The AttributeChecker for second.
221 */
223 Ptr<const AttributeChecker> secondchecker);
225 Ptr<const AttributeChecker> secondchecker) override;
226 typename ns3::PairChecker::checker_pair_type GetCheckers() const override;
227
228 private:
229 /** The first checker. */
231 /** The second checker. */
233};
234
235template <class A, class B>
237 : m_firstchecker(nullptr),
238 m_secondchecker(nullptr)
239{
240}
241
242template <class A, class B>
244 Ptr<const AttributeChecker> secondchecker)
245 : m_firstchecker(firstchecker),
246 m_secondchecker(secondchecker)
247{
248}
249
250template <class A, class B>
251void
253 Ptr<const AttributeChecker> secondchecker)
254{
255 m_firstchecker = firstchecker;
256 m_secondchecker = secondchecker;
257}
258
259template <class A, class B>
262{
263 return std::make_pair(m_firstchecker, m_secondchecker);
264}
265
266} // namespace internal
267
268template <class A, class B>
271{
272 return MakePairChecker<A, B>();
273}
274
275template <class A, class B>
276Ptr<const AttributeChecker>
278{
279 auto checker = MakePairChecker<A, B>();
280 auto acchecker = DynamicCast<PairChecker>(checker);
281 acchecker->SetCheckers(firstchecker, secondchecker);
282 return checker;
283}
284
285template <class A, class B>
286Ptr<AttributeChecker>
288{
289 std::string pairName;
290 std::string underlyingType;
291 typedef PairValue<A, B> T;
292 std::string first_type_name = typeid(typename T::value_type::first_type).name();
293 std::string second_type_name = typeid(typename T::value_type::second_type).name();
294 {
295 std::ostringstream oss;
296 oss << "ns3::PairValue<" << first_type_name << ", " << second_type_name << ">";
297 pairName = oss.str();
298 }
299
300 {
301 std::ostringstream oss;
302 oss << typeid(typename T::value_type).name();
303 underlyingType = oss.str();
304 }
305
306 return MakeSimpleAttributeChecker<T, internal::PairChecker<A, B>>(pairName, underlyingType);
307}
308
309template <class A, class B>
310Ptr<AttributeValue>
312{
313 auto p = Create<PairValue<A, B>>();
314 // deep copy if non-null
315 if (m_value.first)
316 {
317 p->m_value = std::make_pair(DynamicCast<A>(m_value.first->Copy()),
318 DynamicCast<B>(m_value.second->Copy()));
319 }
320 return p;
321}
322
323template <class A, class B>
324bool
326{
327 auto pchecker = DynamicCast<const PairChecker>(checker);
328 if (!pchecker)
329 {
330 return false;
331 }
332
333 std::istringstream iss(value); // copies value
334 iss >> value;
335 auto first = pchecker->GetCheckers().first->CreateValidValue(StringValue(value));
336 if (!first)
337 {
338 return false;
339 }
340
341 auto firstattr = DynamicCast<A>(first);
342 if (!firstattr)
343 {
344 return false;
345 }
346
347 iss >> value;
348 auto second = pchecker->GetCheckers().second->CreateValidValue(StringValue(value));
349 if (!second)
350 {
351 return false;
352 }
353
354 auto secondattr = DynamicCast<B>(second);
355 if (!secondattr)
356 {
357 return false;
358 }
359
360 m_value = std::make_pair(firstattr, secondattr);
361 return true;
362}
363
364template <class A, class B>
365std::string
367{
368 std::ostringstream oss;
369 oss << m_value.first->SerializeToString(checker);
370 oss << " ";
371 oss << m_value.second->SerializeToString(checker);
372
373 return oss.str();
374}
375
376template <class A, class B>
379{
380 return std::make_pair(m_value.first->Get(), m_value.second->Get());
381}
382
383template <class A, class B>
384void
386{
387 m_value = std::make_pair(Create<A>(value.first), Create<B>(value.second));
388}
389
390template <class A, class B>
391template <typename T>
392bool
394{
395 value = T(Get());
396 return true;
397}
398
399template <typename A, typename B, typename T1>
402{
404}
405
406} // namespace ns3
407
408#endif // PAIR_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
AttributeChecker implementation for PairValue.
Definition pair.h:116
virtual void SetCheckers(Ptr< const AttributeChecker > firstchecker, Ptr< const AttributeChecker > secondchecker)=0
Set the individual AttributeChecker for each pair entry.
std::pair< Ptr< const AttributeChecker >, Ptr< const AttributeChecker > > checker_pair_type
Type holding an AttributeChecker for each member of a pair.
Definition pair.h:119
virtual checker_pair_type GetCheckers() const =0
Get the pair of checkers for each pair entry.
AttributeValue implementation for Pair.
Definition pair.h:54
PairValue(const result_type &value)
Construct this PairValue from a std::pair.
Definition pair.h:73
std::pair< first_type, second_type > result_type
Type returned by Get or passed in Set.
Definition pair.h:63
result_type Get() const
Get the stored value as a std::pair.
Definition pair.h:378
bool GetAccessor(T &value) const
Access the Pair value as type T.
Definition pair.h:393
std::invoke_result_t< decltype(&A::Get), A > first_type
Type of abscissa (first entry of pair).
Definition pair.h:59
std::pair< Ptr< A >, Ptr< B > > value_type
Type of value stored in the PairValue.
Definition pair.h:57
value_type m_value
The stored Pair instance.
Definition pair.h:107
std::string SerializeToString(Ptr< const AttributeChecker > checker) const override
Definition pair.h:366
void Set(const result_type &value)
Set the value.
Definition pair.h:385
std::invoke_result_t< decltype(&B::Get), B > second_type
Type of ordinal (second entry of pair).
Definition pair.h:61
bool DeserializeFromString(std::string value, Ptr< const AttributeChecker > checker) override
Definition pair.h:325
Ptr< AttributeValue > Copy() const override
Definition pair.h:311
Smart pointer class similar to boost::intrusive_ptr.
Hold variables of type string.
Definition string.h:45
Internal checker class templated to each AttributeChecker for each entry in the pair.
Definition pair.h:213
Ptr< const AttributeChecker > m_secondchecker
The second checker.
Definition pair.h:232
Ptr< const AttributeChecker > m_firstchecker
The first checker.
Definition pair.h:230
void SetCheckers(Ptr< const AttributeChecker > firstchecker, Ptr< const AttributeChecker > secondchecker) override
Set the individual AttributeChecker for each pair entry.
Definition pair.h:252
ns3::PairChecker::checker_pair_type GetCheckers() const override
Get the pair of checkers for each pair entry.
Definition pair.h:261
PairChecker()
Default c'tor.
Definition pair.h:236
Ptr< const AttributeAccessor > MakePairAccessor(T1 a1)
Create an AttributeAccessor for std::pair<>.
Definition pair.h:401
Ptr< AttributeChecker > MakePairChecker()
Make a PairChecker without abscissa and ordinate AttributeCheckers.
Definition pair.h:287
Ptr< const AttributeAccessor > MakeAccessorHelper(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< AttributeChecker > MakeSimpleAttributeChecker(std::string name, std::string underlying)
A simple string-based attribute checker.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Definition first.py:1
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.