A Discrete-Event Network Simulator
API
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 
38 namespace ns3
39 {
40 
41 // Additional docs for class EnumValue:
60 template <typename T>
61 class EnumValue : public AttributeValue
62 {
63  public:
70  EnumValue(T value);
71  void Set(T value);
72  T Get() const;
73 
74  bool GetAccessor(T& value) const;
75 
76  Ptr<AttributeValue> Copy() const override;
77  std::string SerializeToString(Ptr<const AttributeChecker> checker) const override;
78  bool DeserializeFromString(std::string value, Ptr<const AttributeChecker> checker) override;
79 
80  private:
81  T m_value;
82 };
83 
84 template <typename T>
85 EnumValue<T>::EnumValue() = default;
86 
87 template <typename T>
89  : m_value(value)
90 {
91 }
92 
93 template <typename T>
94 void
96 {
97  m_value = value;
98 }
99 
100 template <typename T>
101 T
103 {
104  return m_value;
105 }
106 
107 template <typename T>
108 bool
110 {
111  value = static_cast<T>(m_value);
112  return true;
113 }
114 
115 template <typename T>
118 {
119  return Create<EnumValue>(*this);
120 }
121 
122 template <typename T>
124 {
125  public:
126  EnumChecker();
127 
133  void AddDefault(T value, std::string name);
139  void Add(T value, std::string name);
140 
146  std::string GetName(T value) const;
147 
153  T GetValue(const std::string name) const;
154 
155  // Inherited
156  bool Check(const AttributeValue& value) const override;
157  std::string GetValueTypeName() const override;
158  bool HasUnderlyingTypeInformation() const override;
159  std::string GetUnderlyingTypeInformation() const override;
160  Ptr<AttributeValue> Create() const override;
161  bool Copy(const AttributeValue& src, AttributeValue& dst) const override;
162 
163  private:
165  using Value = std::pair<T, std::string>;
167  using ValueSet = std::list<Value>;
170 };
171 
192 template <typename T, typename... Ts>
194 MakeEnumChecker(T v, std::string n, Ts... args)
195 {
196  Ptr<EnumChecker<T>> checker = Create<EnumChecker<T>>();
197  checker->AddDefault(v, n);
198  return MakeEnumChecker(checker, args...);
199 }
200 
212 template <typename T, typename... Ts>
213 Ptr<const AttributeChecker>
214 MakeEnumChecker(Ptr<EnumChecker<T>> checker, T v, std::string n, Ts... args)
215 {
216  checker->Add(v, n);
217  return MakeEnumChecker(checker, args...);
218 }
219 
226 // inline to allow tail call optimization
227 template <typename T>
228 inline Ptr<const AttributeChecker>
230 {
231  return checker;
232 }
233 
234 template <typename T, typename T1>
235 Ptr<const AttributeAccessor>
237 {
238  return MakeAccessorHelper<EnumValue<T>>(a1);
239 }
240 
241 template <typename T, typename T1, typename T2>
242 Ptr<const AttributeAccessor>
243 MakeEnumAccessor(T1 a1, T2 a2)
244 {
245  return MakeAccessorHelper<EnumValue<T>>(a1, a2);
246 }
247 
248 template <typename T>
249 std::string
251 {
252  const auto p = dynamic_cast<const EnumChecker<T>*>(PeekPointer(checker));
253  NS_ASSERT(p != nullptr);
254  std::string name = p->GetName(m_value);
255  return name;
256 }
257 
258 template <typename T>
259 bool
261 {
262  const auto p = dynamic_cast<const EnumChecker<T>*>(PeekPointer(checker));
263  NS_ASSERT(p != nullptr);
264  m_value = p->GetValue(value);
265  return true;
266 }
267 
268 template <typename T>
270 {
271 }
272 
273 template <typename T>
274 void
275 EnumChecker<T>::AddDefault(T value, std::string name)
276 {
277  m_valueSet.emplace_front(value, name);
278 }
279 
280 template <typename T>
281 void
282 EnumChecker<T>::Add(T value, std::string name)
283 {
284  m_valueSet.emplace_back(value, name);
285 }
286 
287 template <typename T>
288 std::string
290 {
291  auto it = std::find_if(m_valueSet.begin(), m_valueSet.end(), [value](Value v) {
292  return v.first == value;
293  });
294 
295  NS_ASSERT_MSG(it != m_valueSet.end(),
296  "invalid enum value " << static_cast<int>(value)
297  << "! Missed entry in MakeEnumChecker?");
298  return it->second;
299 }
300 
301 template <typename T>
302 T
303 EnumChecker<T>::GetValue(const std::string name) const
304 {
305  auto it = std::find_if(m_valueSet.begin(), m_valueSet.end(), [name](Value v) {
306  return v.second == name;
307  });
309  it != m_valueSet.end(),
310  "name "
311  << name
312  << " is not a valid enum value. Missed entry in MakeEnumChecker?\nAvailable values: "
313  << std::accumulate(m_valueSet.begin(),
314  m_valueSet.end(),
315  std::string{},
316  [](std::string a, Value v) {
317  if (a.empty())
318  {
319  return v.second;
320  }
321  else
322  {
323  return std::move(a) + ", " + v.second;
324  }
325  }));
326  return it->first;
327 }
328 
329 template <typename T>
330 bool
332 {
333  const auto p = dynamic_cast<const EnumValue<T>*>(&value);
334  if (!p)
335  {
336  return false;
337  }
338  auto pvalue = p->Get();
339  auto it = std::find_if(m_valueSet.begin(), m_valueSet.end(), [pvalue](Value v) {
340  return v.first == pvalue;
341  });
342  return (it != m_valueSet.end());
343 }
344 
345 template <typename T>
346 std::string
348 {
349  return "ns3::EnumValue<" + std::string(typeid(T).name()) + ">";
350 }
351 
352 template <typename T>
353 bool
355 {
356  return true;
357 }
358 
359 template <typename T>
360 std::string
362 {
363  std::ostringstream oss;
364  bool moreValues = false;
365  for (const auto& i : m_valueSet)
366  {
367  oss << (moreValues ? "|" : "") << i.second;
368  moreValues = true;
369  }
370  return oss.str();
371 }
372 
373 template <typename T>
376 {
377  return ns3::Create<EnumValue<T>>();
378 }
379 
380 template <typename T>
381 bool
382 EnumChecker<T>::Copy(const AttributeValue& source, AttributeValue& destination) const
383 {
384  const auto src = dynamic_cast<const EnumValue<T>*>(&source);
385  auto dst = dynamic_cast<EnumValue<T>*>(&destination);
386  if (!src || !dst)
387  {
388  return false;
389  }
390  *dst = *src;
391  return true;
392 }
393 
394 } // namespace ns3
395 
396 #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
Ptr< AttributeValue > Create() const override
Definition: enum.h:375
void Add(T value, std::string name)
Add a new value.
Definition: enum.h:282
bool HasUnderlyingTypeInformation() const override
Definition: enum.h:354
std::list< Value > ValueSet
Type of container for storing Enum values and symbol names.
Definition: enum.h:167
std::string GetName(T value) const
Get the enum symbol name by value.
Definition: enum.h:289
bool Copy(const AttributeValue &src, AttributeValue &dst) const override
Copy the source to the destination.
Definition: enum.h:382
void AddDefault(T value, std::string name)
Add a default value.
Definition: enum.h:275
std::string GetValueTypeName() const override
Definition: enum.h:347
T GetValue(const std::string name) const
Get the enum value by name.
Definition: enum.h:303
bool Check(const AttributeValue &value) const override
Definition: enum.h:331
std::pair< T, std::string > Value
Type for the pair value, name.
Definition: enum.h:165
ValueSet m_valueSet
The stored Enum values and symbol names.
Definition: enum.h:169
std::string GetUnderlyingTypeInformation() const override
Definition: enum.h:361
Hold variables of type enum.
Definition: enum.h:62
void Set(T value)
Definition: enum.h:95
bool DeserializeFromString(std::string value, Ptr< const AttributeChecker > checker) override
Definition: enum.h:260
T Get() const
Definition: enum.h:102
T m_value
The stored value.
Definition: enum.h:81
bool GetAccessor(T &value) const
Definition: enum.h:109
std::string SerializeToString(Ptr< const AttributeChecker > checker) const override
Definition: enum.h:250
Ptr< AttributeValue > Copy() const override
Definition: enum.h:117
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< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition: ptr.h:442
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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:194
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Definition: enum.h:236
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:449
Ptr< T > Copy(Ptr< T > object)
Return a deep copy of a Ptr.
Definition: ptr.h:610
value
Definition: second.py:48