A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
enum.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2008 INRIA
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
7 */
8#ifndef ENUM_VALUE_H
9#define ENUM_VALUE_H
10
12#include "attribute.h"
13#include "demangle.h"
14
15#include <algorithm> // find_if
16#include <list>
17#include <numeric> // std::accumulate
18#include <sstream>
19#include <type_traits>
20#include <typeinfo>
21
22/**
23 * @file
24 * @ingroup attribute_Enum
25 * ns3::EnumValue attribute value declarations.
26 */
27
28namespace ns3
29{
30
31// Additional docs for class EnumValue:
32/**
33 * Hold variables of type \c enum
34 *
35 * This class can be used to hold variables of any kind
36 * of enum.
37 *
38 * This is often used with ObjectFactory and Config to bind
39 * the value of a particular enum to an Attribute or Config name.
40 * For example,
41 * @code
42 * Ptr<RateErrorModel> model = CreateObjectWithAttributes<RateErrorModel> (
43 * "ErrorRate", DoubleValue (0.05),
44 * "ErrorUnit", EnumValue (RateErrorModel::ERROR_UNIT_PACKET));
45 *
46 * Config::SetDefault ("ns3::RipNg::SplitHorizon",
47 * EnumValue (RipNg::NO_SPLIT_HORIZON));
48 * @endcode
49 */
50template <typename T>
52{
53 public:
55 EnumValue(const T& value);
56 void Set(T value);
57 T Get() const;
58
59 bool GetAccessor(T& value) const;
60
61 Ptr<AttributeValue> Copy() const override;
62 std::string SerializeToString(Ptr<const AttributeChecker> checker) const override;
63 bool DeserializeFromString(std::string value, Ptr<const AttributeChecker> checker) override;
64
65 private:
66 T m_value{}; //!< The stored value.
67};
68
69template <typename T>
70EnumValue<T>::EnumValue() = default;
71
72template <typename T>
74 : m_value(value)
75{
76}
77
78template <typename T>
79void
81{
82 m_value = value;
83}
84
85template <typename T>
86T
88{
89 return m_value;
90}
91
92template <typename T>
93bool
95{
96 value = static_cast<T>(m_value);
97 return true;
98}
99
100template <typename T>
103{
104 return Create<EnumValue>(*this);
105}
106
107template <typename T>
109{
110 public:
111 EnumChecker();
112
113 /**
114 * Add a default value.
115 * @param [in] value The value.
116 * @param [in] name Then enum symbol name.
117 */
118 void AddDefault(T value, std::string name);
119 /**
120 * Add a new value.
121 * @param [in] value The value.
122 * @param [in] name The enum symbol name.
123 */
124 void Add(T value, std::string name);
125
126 /**
127 * Get the enum symbol name by value.
128 * @param [in] value The value.
129 * @return The enum symbol name.
130 */
131 std::string GetName(T value) const;
132
133 /**
134 * Get the enum value by name.
135 * @param [in] name Then enum symbol name.
136 * @returns The enum value.
137 */
138 T GetValue(const std::string name) const;
139
140 // Inherited
141 bool Check(const AttributeValue& value) const override;
142 std::string GetValueTypeName() const override;
143 bool HasUnderlyingTypeInformation() const override;
144 std::string GetUnderlyingTypeInformation() const override;
145 Ptr<AttributeValue> Create() const override;
146 bool Copy(const AttributeValue& src, AttributeValue& dst) const override;
147
148 private:
149 /** Type for the pair value, name */
150 using Value = std::pair<T, std::string>;
151 /** Type of container for storing Enum values and symbol names. */
152 using ValueSet = std::list<Value>;
153 /** The stored Enum values and symbol names. */
155};
156
157/**
158 * Make an EnumChecker pre-configured with a set of allowed
159 * values by name.
160 *
161 * Values are normally given as fully qualified enum symbols
162 * with matching names. For example,
163 * \c MakeEnumChecker (RipNg::SPLIT_HORIZON, "ns3::RipNg::SplitHorizon");
164 *
165 * As many additional enum value, name pairs as desired can be passed
166 * as arguments.
167 *
168 * @see AttributeChecker
169 *
170 * @tparam Ts The type list of additional parameters. Additional parameters
171 * should be T, string pairs.
172 * @returns The AttributeChecker
173 * @param [in] v The default enum value.
174 * @param [in] n The corresponding name.
175 * @param [in] args Any additional arguments.
176 *
177 * @hidecaller
178 */
179template <typename T, typename... Ts>
181MakeEnumChecker(T v, std::string n, Ts... args)
182{
184 checker->AddDefault(v, n);
185 return MakeEnumChecker(checker, args...);
186}
187
188/**
189 * Handler for enum value, name pairs other than the default.
190 *
191 * @tparam Ts The type list of additional parameters. Additional parameters
192 * should be T, string pairs.
193 * @returns The AttributeChecker
194 * @param [in] checker The AttributeChecker.
195 * @param [in] v The next enum value.
196 * @param [in] n The corresponding name.
197 * @param [in] args Any additional arguments.
198 */
199template <typename T, typename... Ts>
200Ptr<const AttributeChecker>
201MakeEnumChecker(Ptr<EnumChecker<T>> checker, T v, std::string n, Ts... args)
202{
203 checker->Add(v, n);
204 return MakeEnumChecker(checker, args...);
205}
206
207/**
208 * Terminate the recursion of variadic arguments.
209 *
210 * @returns The \p checker
211 * @param [in] checker The AttributeChecker.
212 */
213// inline to allow tail call optimization
214template <typename T>
215inline Ptr<const AttributeChecker>
217{
218 return checker;
219}
220
221template <typename T, typename T1>
222Ptr<const AttributeAccessor>
224{
226}
227
228template <typename T, typename T1, typename T2>
229Ptr<const AttributeAccessor>
230MakeEnumAccessor(T1 a1, T2 a2)
231{
232 return MakeAccessorHelper<EnumValue<T>>(a1, a2);
233}
234
235template <typename T>
236std::string
238{
239 const auto p = dynamic_cast<const EnumChecker<T>*>(PeekPointer(checker));
240 NS_ASSERT(p != nullptr);
241 std::string name = p->GetName(m_value);
242 return name;
243}
244
245template <typename T>
246bool
248{
249 const auto p = dynamic_cast<const EnumChecker<T>*>(PeekPointer(checker));
250 NS_ASSERT(p != nullptr);
251 m_value = p->GetValue(value);
252 return true;
253}
254
255template <typename T>
259
260template <typename T>
261void
262EnumChecker<T>::AddDefault(T value, std::string name)
263{
264 m_valueSet.emplace_front(value, name);
265}
266
267template <typename T>
268void
269EnumChecker<T>::Add(T value, std::string name)
270{
271 m_valueSet.emplace_back(value, name);
272}
273
274template <typename T>
275std::string
277{
278 auto it = std::find_if(m_valueSet.begin(), m_valueSet.end(), [value](Value v) {
279 return v.first == value;
280 });
281
282 NS_ASSERT_MSG(it != m_valueSet.end(),
283 "invalid enum value " << static_cast<int>(value)
284 << "! Missed entry in MakeEnumChecker?");
285 return it->second;
286}
287
288template <typename T>
289T
290EnumChecker<T>::GetValue(const std::string name) const
291{
292 auto it = std::find_if(m_valueSet.begin(), m_valueSet.end(), [name](Value v) {
293 return v.second == name;
294 });
296 it != m_valueSet.end(),
297 "name "
298 << name
299 << " is not a valid enum value. Missed entry in MakeEnumChecker?\nAvailable values: "
300 << std::accumulate(m_valueSet.begin(),
301 m_valueSet.end(),
302 std::string{},
303 [](std::string a, Value v) {
304 if (a.empty())
305 {
306 return v.second;
307 }
308 else
309 {
310 return std::move(a) + ", " + v.second;
311 }
312 }));
313 return it->first;
314}
315
316template <typename T>
317bool
319{
320 const auto p = dynamic_cast<const EnumValue<T>*>(&value);
321 if (!p)
322 {
323 return false;
324 }
325 auto pvalue = p->Get();
326 auto it = std::find_if(m_valueSet.begin(), m_valueSet.end(), [pvalue](Value v) {
327 return v.first == pvalue;
328 });
329 return (it != m_valueSet.end());
330}
331
332template <typename T>
333std::string
335{
336 return "ns3::EnumValue<" + Demangle(typeid(T).name()) + ">";
337}
338
339template <typename T>
340bool
342{
343 return true;
344}
345
346template <typename T>
347std::string
349{
350 std::ostringstream oss;
351 bool moreValues = false;
352 for (const auto& i : m_valueSet)
353 {
354 oss << (moreValues ? "|" : "") << i.second;
355 moreValues = true;
356 }
357 return oss.str();
358}
359
360template <typename T>
363{
364 return ns3::Create<EnumValue<T>>();
365}
366
367template <typename T>
368bool
369EnumChecker<T>::Copy(const AttributeValue& source, AttributeValue& destination) const
370{
371 const auto src = dynamic_cast<const EnumValue<T>*>(&source);
372 auto dst = dynamic_cast<EnumValue<T>*>(&destination);
373 if (!src || !dst)
374 {
375 return false;
376 }
377 *dst = *src;
378 return true;
379}
380
381} // namespace ns3
382
383#endif /* ENUM_VALUE_H */
ns3::MakeAccessorHelper declarations and template implementations.
ns3::AttributeValue, ns3::AttributeAccessor and ns3::AttributeChecker declarations.
uint32_t v
Hold a value for an Attribute.
Definition attribute.h:59
AttributeChecker implementation for EnumValue.
Definition enum.h:109
Ptr< AttributeValue > Create() const override
Definition enum.h:362
void Add(T value, std::string name)
Add a new value.
Definition enum.h:269
bool HasUnderlyingTypeInformation() const override
Definition enum.h:341
std::list< Value > ValueSet
Type of container for storing Enum values and symbol names.
Definition enum.h:152
std::string GetName(T value) const
Get the enum symbol name by value.
Definition enum.h:276
bool Copy(const AttributeValue &src, AttributeValue &dst) const override
Copy the source to the destination.
Definition enum.h:369
void AddDefault(T value, std::string name)
Add a default value.
Definition enum.h:262
std::string GetValueTypeName() const override
Definition enum.h:334
T GetValue(const std::string name) const
Get the enum value by name.
Definition enum.h:290
bool Check(const AttributeValue &value) const override
Definition enum.h:318
std::pair< T, std::string > Value
Type for the pair value, name.
Definition enum.h:150
ValueSet m_valueSet
The stored Enum values and symbol names.
Definition enum.h:154
std::string GetUnderlyingTypeInformation() const override
Definition enum.h:348
Hold variables of type enum.
Definition enum.h:52
void Set(T value)
Set the value.
Definition enum.h:80
bool DeserializeFromString(std::string value, Ptr< const AttributeChecker > checker) override
Definition enum.h:247
T Get() const
Definition enum.h:87
T m_value
The stored value.
Definition enum.h:66
bool GetAccessor(T &value) const
Access the Enum value as type T.
Definition enum.h:94
std::string SerializeToString(Ptr< const AttributeChecker > checker) const override
Definition enum.h:237
Ptr< AttributeValue > Copy() const override
Definition enum.h:102
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition assert.h:75
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition enum.h:223
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:454
Every class exported by the ns3 library is enclosed in the ns3 namespace.
U * PeekPointer(const Ptr< U > &p)
Definition ptr.h:463
std::string Demangle(const std::string &mangled)
Definition demangle.cc:69
Ptr< const AttributeChecker > MakeEnumChecker(T v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition enum.h:181