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