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
70 /**
71 * Construct this PairValue from a std::pair
72 *
73 * @param [in] value Value with which to construct.
74 */
75 PairValue(const result_type& value)
76 {
77 Set(value);
78 } // "import" constructor
79
80 // Inherited
81 Ptr<AttributeValue> Copy() const override;
82 bool DeserializeFromString(std::string value, Ptr<const AttributeChecker> checker) override;
83 std::string SerializeToString(Ptr<const AttributeChecker> checker) const override;
84
85 /**
86 * Get the stored value as a std::pair.
87 *
88 * This differs from the actual value stored in the object which is
89 * a pair of Ptr<AV> where AV is a class derived from AttributeValue.
90 * @return stored value as std::pair<A, B>.
91 */
92 result_type Get() const;
93 /**
94 * Set the value.
95 * @param [in] value The value to adopt.
96 */
97 void Set(const result_type& value);
98
99 /**
100 * Access the Pair value as type \p T.
101 * @tparam T \explicit The type to cast to.
102 * @param [out] value The Pair value, as type \p T.
103 * @returns true.
104 */
105 template <typename T>
106 bool GetAccessor(T& value) const;
107
108 private:
109 value_type m_value; //!< The stored Pair instance.
110};
111
112/**
113 * @ingroup attribute_Pair
114 * AttributeChecker implementation for PairValue.
115 * @see AttributeChecker
116 */
118{
119 public:
120 /** Type holding an AttributeChecker for each member of a pair. */
121 typedef std::pair<Ptr<const AttributeChecker>, Ptr<const AttributeChecker>> checker_pair_type;
122
123 /**
124 * Set the individual AttributeChecker for each pair entry.
125 *
126 * \param[in] firstchecker AttributeChecker for abscissa.
127 * \param[in] secondchecker AttributeChecker for ordinate.
128 */
129 virtual void SetCheckers(Ptr<const AttributeChecker> firstchecker,
130 Ptr<const AttributeChecker> secondchecker) = 0;
131
132 /**
133 * Get the pair of checkers for each pair entry.
134 *
135 * @return std::pair with AttributeChecker for each of abscissa and ordinate.
136 */
137 virtual checker_pair_type GetCheckers() const = 0;
138};
139
140/**
141 * @ingroup attribute_Pair
142 *
143 * Make a PairChecker from a PairValue.
144 *
145 * This function returns a Pointer to a non-const instance to
146 * allow subsequent setting of the underlying AttributeCheckers.
147 * \param[in] value PairValue from which to derive abscissa and ordinate types.
148 * @return Pointer to PairChecker instance.
149 */
150template <class A, class B>
152
153/**
154 * @ingroup attribute_Pair
155 *
156 * Make a PairChecker from abscissa and ordinate AttributeCheckers.
157 *
158 * This function returns a Pointer to a const instance since both
159 * underlying AttributeCheckers are set.
160 *
161 * \param[in] firstchecker AttributeChecker for abscissa.
162 * \param[in] secondchecker AttributeChecker for ordinate.
163 * @return Pointer to PairChecker instance.
164 */
165template <class A, class B>
167 Ptr<const AttributeChecker> secondchecker);
168
169/**
170 * @ingroup attribute_Pair
171 *
172 * Make a PairChecker without abscissa and ordinate AttributeCheckers.
173 *
174 * @return Pointer to PairChecker instance.
175 */
176template <class A, class B>
178
179/**
180 * @ingroup attribute_Pair
181 *
182 * Create an AttributeAccessor for std::pair<>.
183 * @tparam A \explicit The type of pair.first.
184 * @tparam B \explicit The type of pair.second.
185 * @tparam T1 \deduced The argument pair type.
186 * @param [in] a1 The std::pair to be accessed.
187 * @returns The AttributeAccessor.
188 */
189template <typename A, typename B, typename T1>
191
192} // namespace ns3
193
194/*****************************************************************************
195 * Implementation below
196 *****************************************************************************/
197
198namespace ns3
199{
200
201// This internal class defines templated PairChecker class that is instantiated
202// in MakePairChecker. The non-templated base ns3::PairChecker is returned in that
203// function. This is the same pattern as ObjectPtrContainer.
204namespace internal
205{
206
207/**
208 * @ingroup attribute_Pair
209 *
210 * Internal checker class templated to each AttributeChecker
211 * for each entry in the pair.
212 */
213template <class A, class B>
215{
216 public:
217 /** Default c'tor. */
218 PairChecker();
219 /**
220 * Construct from a pair of AttributeChecker's.
221 * @param firstchecker The AttributeChecker for first.
222 * @param secondchecker The AttributeChecker for second.
223 */
225 Ptr<const AttributeChecker> secondchecker);
227 Ptr<const AttributeChecker> secondchecker) override;
228 typename ns3::PairChecker::checker_pair_type GetCheckers() const override;
229
230 private:
231 /** The first checker. */
233 /** The second checker. */
235};
236
237template <class A, class B>
239 : m_firstchecker(nullptr),
240 m_secondchecker(nullptr)
241{
242}
243
244template <class A, class B>
246 Ptr<const AttributeChecker> secondchecker)
247 : m_firstchecker(firstchecker),
248 m_secondchecker(secondchecker)
249{
250}
251
252template <class A, class B>
253void
255 Ptr<const AttributeChecker> secondchecker)
256{
257 m_firstchecker = firstchecker;
258 m_secondchecker = secondchecker;
259}
260
261template <class A, class B>
264{
265 return std::make_pair(m_firstchecker, m_secondchecker);
266}
267
268} // namespace internal
269
270template <class A, class B>
273{
274 return MakePairChecker<A, B>();
275}
276
277template <class A, class B>
278Ptr<const AttributeChecker>
280{
281 auto checker = MakePairChecker<A, B>();
282 auto acchecker = DynamicCast<PairChecker>(checker);
283 acchecker->SetCheckers(firstchecker, secondchecker);
284 return checker;
285}
286
287template <class A, class B>
288Ptr<AttributeChecker>
290{
291 std::string pairName;
292 std::string underlyingType;
293 typedef PairValue<A, B> T;
294 std::string first_type_name = typeid(typename T::value_type::first_type).name();
295 std::string second_type_name = typeid(typename T::value_type::second_type).name();
296 {
297 std::ostringstream oss;
298 oss << "ns3::PairValue<" << first_type_name << ", " << second_type_name << ">";
299 pairName = oss.str();
300 }
301
302 {
303 std::ostringstream oss;
304 oss << typeid(typename T::value_type).name();
305 underlyingType = oss.str();
306 }
307
308 return MakeSimpleAttributeChecker<T, internal::PairChecker<A, B>>(pairName, underlyingType);
309}
310
311template <class A, class B>
312Ptr<AttributeValue>
314{
315 auto p = Create<PairValue<A, B>>();
316 // deep copy if non-null
317 if (m_value.first)
318 {
319 p->m_value = std::make_pair(DynamicCast<A>(m_value.first->Copy()),
320 DynamicCast<B>(m_value.second->Copy()));
321 }
322 return p;
323}
324
325template <class A, class B>
326bool
328{
329 auto pchecker = DynamicCast<const PairChecker>(checker);
330 if (!pchecker)
331 {
332 return false;
333 }
334
335 std::istringstream iss(value); // copies value
336 iss >> value;
337 auto first = pchecker->GetCheckers().first->CreateValidValue(StringValue(value));
338 if (!first)
339 {
340 return false;
341 }
342
343 auto firstattr = DynamicCast<A>(first);
344 if (!firstattr)
345 {
346 return false;
347 }
348
349 iss >> value;
350 auto second = pchecker->GetCheckers().second->CreateValidValue(StringValue(value));
351 if (!second)
352 {
353 return false;
354 }
355
356 auto secondattr = DynamicCast<B>(second);
357 if (!secondattr)
358 {
359 return false;
360 }
361
362 m_value = std::make_pair(firstattr, secondattr);
363 return true;
364}
365
366template <class A, class B>
367std::string
369{
370 std::ostringstream oss;
371 oss << m_value.first->SerializeToString(checker);
372 oss << " ";
373 oss << m_value.second->SerializeToString(checker);
374
375 return oss.str();
376}
377
378template <class A, class B>
381{
382 return std::make_pair(m_value.first->Get(), m_value.second->Get());
383}
384
385template <class A, class B>
386void
388{
389 m_value = std::make_pair(Create<A>(value.first), Create<B>(value.second));
390}
391
392template <class A, class B>
393template <typename T>
394bool
396{
397 value = T(Get());
398 return true;
399}
400
401template <typename A, typename B, typename T1>
404{
406}
407
408} // namespace ns3
409
410#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:118
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:121
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:75
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:380
bool GetAccessor(T &value) const
Access the Pair value as type T.
Definition pair.h:395
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:109
std::string SerializeToString(Ptr< const AttributeChecker > checker) const override
Definition pair.h:368
void Set(const result_type &value)
Set the value.
Definition pair.h:387
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:327
Ptr< AttributeValue > Copy() const override
Definition pair.h:313
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:215
Ptr< const AttributeChecker > m_secondchecker
The second checker.
Definition pair.h:234
Ptr< const AttributeChecker > m_firstchecker
The first checker.
Definition pair.h:232
void SetCheckers(Ptr< const AttributeChecker > firstchecker, Ptr< const AttributeChecker > secondchecker) override
Set the individual AttributeChecker for each pair entry.
Definition pair.h:254
ns3::PairChecker::checker_pair_type GetCheckers() const override
Get the pair of checkers for each pair entry.
Definition pair.h:263
PairChecker()
Default c'tor.
Definition pair.h:238
Ptr< const AttributeAccessor > MakePairAccessor(T1 a1)
Create an AttributeAccessor for std::pair<>.
Definition pair.h:403
Ptr< AttributeChecker > MakePairChecker()
Make a PairChecker without abscissa and ordinate AttributeCheckers.
Definition pair.h:289
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.