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 */
177template <typename T, typename... Ts>
179MakeEnumChecker(T v, std::string n, Ts... args)
180{
182 checker->AddDefault(v, n);
183 return MakeEnumChecker(checker, args...);
184}
185
186/**
187 * Handler for enum value, name pairs other than the default.
188 *
189 * \tparam Ts The type list of additional parameters. Additional parameters
190 * should be T, string pairs.
191 * \returns The AttributeChecker
192 * \param [in] checker The AttributeChecker.
193 * \param [in] v The next enum value.
194 * \param [in] n The corresponding name.
195 * \param [in] args Any additional arguments.
196 */
197template <typename T, typename... Ts>
198Ptr<const AttributeChecker>
199MakeEnumChecker(Ptr<EnumChecker<T>> checker, T v, std::string n, Ts... args)
200{
201 checker->Add(v, n);
202 return MakeEnumChecker(checker, args...);
203}
204
205/**
206 * Terminate the recursion of variadic arguments.
207 *
208 * \returns The \p checker
209 * \param [in] checker The AttributeChecker.
210 */
211// inline to allow tail call optimization
212template <typename T>
213inline Ptr<const AttributeChecker>
215{
216 return checker;
217}
218
219template <typename T, typename T1>
220Ptr<const AttributeAccessor>
222{
224}
225
226template <typename T, typename T1, typename T2>
227Ptr<const AttributeAccessor>
228MakeEnumAccessor(T1 a1, T2 a2)
229{
230 return MakeAccessorHelper<EnumValue<T>>(a1, a2);
231}
232
233template <typename T>
234std::string
236{
237 const auto p = dynamic_cast<const EnumChecker<T>*>(PeekPointer(checker));
238 NS_ASSERT(p != nullptr);
239 std::string name = p->GetName(m_value);
240 return name;
241}
242
243template <typename T>
244bool
246{
247 const auto p = dynamic_cast<const EnumChecker<T>*>(PeekPointer(checker));
248 NS_ASSERT(p != nullptr);
249 m_value = p->GetValue(value);
250 return true;
251}
252
253template <typename T>
257
258template <typename T>
259void
260EnumChecker<T>::AddDefault(T value, std::string name)
261{
262 m_valueSet.emplace_front(value, name);
263}
264
265template <typename T>
266void
267EnumChecker<T>::Add(T value, std::string name)
268{
269 m_valueSet.emplace_back(value, name);
270}
271
272template <typename T>
273std::string
275{
276 auto it = std::find_if(m_valueSet.begin(), m_valueSet.end(), [value](Value v) {
277 return v.first == value;
278 });
279
280 NS_ASSERT_MSG(it != m_valueSet.end(),
281 "invalid enum value " << static_cast<int>(value)
282 << "! Missed entry in MakeEnumChecker?");
283 return it->second;
284}
285
286template <typename T>
287T
288EnumChecker<T>::GetValue(const std::string name) const
289{
290 auto it = std::find_if(m_valueSet.begin(), m_valueSet.end(), [name](Value v) {
291 return v.second == name;
292 });
294 it != m_valueSet.end(),
295 "name "
296 << name
297 << " is not a valid enum value. Missed entry in MakeEnumChecker?\nAvailable values: "
298 << std::accumulate(m_valueSet.begin(),
299 m_valueSet.end(),
300 std::string{},
301 [](std::string a, Value v) {
302 if (a.empty())
303 {
304 return v.second;
305 }
306 else
307 {
308 return std::move(a) + ", " + v.second;
309 }
310 }));
311 return it->first;
312}
313
314template <typename T>
315bool
317{
318 const auto p = dynamic_cast<const EnumValue<T>*>(&value);
319 if (!p)
320 {
321 return false;
322 }
323 auto pvalue = p->Get();
324 auto it = std::find_if(m_valueSet.begin(), m_valueSet.end(), [pvalue](Value v) {
325 return v.first == pvalue;
326 });
327 return (it != m_valueSet.end());
328}
329
330template <typename T>
331std::string
333{
334 return "ns3::EnumValue<" + Demangle(typeid(T).name()) + ">";
335}
336
337template <typename T>
338bool
340{
341 return true;
342}
343
344template <typename T>
345std::string
347{
348 std::ostringstream oss;
349 bool moreValues = false;
350 for (const auto& i : m_valueSet)
351 {
352 oss << (moreValues ? "|" : "") << i.second;
353 moreValues = true;
354 }
355 return oss.str();
356}
357
358template <typename T>
361{
362 return ns3::Create<EnumValue<T>>();
363}
364
365template <typename T>
366bool
367EnumChecker<T>::Copy(const AttributeValue& source, AttributeValue& destination) const
368{
369 const auto src = dynamic_cast<const EnumValue<T>*>(&source);
370 auto dst = dynamic_cast<EnumValue<T>*>(&destination);
371 if (!src || !dst)
372 {
373 return false;
374 }
375 *dst = *src;
376 return true;
377}
378
379} // namespace ns3
380
381#endif /* ENUM_VALUE_H */
ns3::MakeAccessorHelper declarations and template implementations.
ns3::AttributeValue, ns3::AttributeAccessor and ns3::AttributeChecker declarations.
Represent the type of an attribute.
Definition attribute.h:157
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:360
void Add(T value, std::string name)
Add a new value.
Definition enum.h:267
bool HasUnderlyingTypeInformation() const override
Definition enum.h:339
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:274
bool Copy(const AttributeValue &src, AttributeValue &dst) const override
Copy the source to the destination.
Definition enum.h:367
void AddDefault(T value, std::string name)
Add a default value.
Definition enum.h:260
std::string GetValueTypeName() const override
Definition enum.h:332
T GetValue(const std::string name) const
Get the enum value by name.
Definition enum.h:288
bool Check(const AttributeValue &value) const override
Definition enum.h:316
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:346
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:245
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:235
Ptr< AttributeValue > Copy() const override
Definition enum.h:102
Smart pointer class similar to boost::intrusive_ptr.
#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:221
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:436
Every class exported by the ns3 library is enclosed in the ns3 namespace.
U * PeekPointer(const Ptr< U > &p)
Definition ptr.h:443
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:179