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