EnumIface.hh
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 Open Source Robotics Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16 */
17 #ifndef _GAZEBO_ENUMITERATOR_HH_
18 #define _GAZEBO_ENUMITERATOR_HH_
19 
20 #include <string>
21 #include <vector>
22 #include <algorithm>
23 #include "gazebo/util/system.hh"
24 #include "gazebo/common/Assert.hh"
25 
26 namespace gazebo
27 {
28  namespace common
29  {
39  #define GZ_ENUM(enumType, begin, end, ...) \
40  template<> GZ_COMMON_VISIBLE enumType \
41  common::EnumIface<enumType>::range[] = {begin, end}; \
42  template<> GZ_COMMON_VISIBLE \
43  std::vector<std::string> common::EnumIface<enumType>::names = {__VA_ARGS__};
44 
47  template<typename T>
48  class EnumIface
49  {
52  public: static T Begin()
53  {
54  return range[0];
55  }
56 
59  public: static T End()
60  {
61  return range[1];
62  }
63 
69  static std::string Str(T const &_e)
70  {
71  if (static_cast<unsigned int>(_e) < names.size())
72  return names[static_cast<unsigned int>(_e)];
73  else
74  return "";
75  }
76 
82  static void Set(T &_e, const std::string &_str)
83  {
84  static auto begin = std::begin(names);
85  static auto end = std::end(names);
86 
87  auto find = std::find(begin, end, _str);
88  if (find != end)
89  {
90  _e = static_cast<T>(std::distance(begin, find));
91  }
92  }
93 
96  public: static T range[2];
97 
101  public: static std::vector<std::string> names;
102  };
103 
132  template<typename Enum>
133  class EnumIterator
134  : std::iterator<std::bidirectional_iterator_tag, Enum>
135  {
137  public: EnumIterator() : c(this->End())
138  {
139  }
140 
143  // cppcheck-suppress noExplicitConstructor
144  public: EnumIterator(const Enum _c) : c(_c)
145  {
146  GZ_ASSERT(this->c >= this->Begin() && this->c <= this->End(),
147  "Invalid enum value in EnumIterator constructor");
148  }
149 
152  public: EnumIterator &operator=(const Enum _c)
153  {
154  GZ_ASSERT(_c >= this->Begin() && _c <= this->End(),
155  "Invalid operator= value in EnumIterator");
156  this->c = _c;
157  return *this;
158  }
159 
162  public: static Enum Begin()
163  {
164  return EnumIface<Enum>::Begin();
165  }
166 
169  public: static Enum End()
170  {
171  return EnumIface<Enum>::End();
172  }
173 
176  public: EnumIterator &operator++()
177  {
178  GZ_ASSERT(this->c != this->End(), "Incrementing past end of enum");
179  this->c = static_cast<Enum>(static_cast<int>(this->c) + 1);
180  return *this;
181  }
182 
185  public: EnumIterator operator++(const int)
186  {
187  GZ_ASSERT(this->c != this->End(), "Incrementing past end of enum");
188  EnumIterator cpy(*this);
189  ++*this;
190  return cpy;
191  }
192 
195  public: EnumIterator &operator--()
196  {
197  GZ_ASSERT(this->c != this->Begin(), "decrementing beyond begin?");
198  this->c = static_cast<Enum>(static_cast<int>(this->c) - 1);
199  return *this;
200  }
201 
204  public: EnumIterator operator--(const int)
205  {
206  GZ_ASSERT(this->c != this->Begin(), "Decrementing beyond beginning.");
207  EnumIterator cpy(*this);
208  --*this;
209  return cpy;
210  }
211 
214  public: Enum operator*() const
215  {
216  GZ_ASSERT(this->c != this->End(), "Cannot dereference end iterator");
217  return c;
218  }
219 
222  public: Enum Value() const
223  {
224  return this->c;
225  }
226 
230  private: Enum c;
231  };
232 
237  template<typename Enum>
238  bool operator==(EnumIterator<Enum> _e1, EnumIterator<Enum> _e2)
239  {
240  return _e1.Value() == _e2.Value();
241  }
242 
247  template<typename Enum>
248  bool operator!=(EnumIterator<Enum> _e1, EnumIterator<Enum> _e2)
249  {
250  return !(_e1 == _e2);
251  }
252  }
253 }
254 #endif
#define GZ_ASSERT(_expr, _msg)
This macro define the standard way of launching an exception inside gazebo.
Definition: Assert.hh:24
GAZEBO_VISIBLE void Set(common::Image &_img, const msgs::Image &_msg)
Convert a msgs::Image to a common::Image.