EnumIface.hh
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015-2016 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/common/Assert.hh"
24 
25 namespace gazebo
26 {
27  namespace common
28  {
38  #define GZ_ENUM(enumType, begin, end, ...) \
39  template<> enumType common::EnumIface<enumType>::range[] = {begin, end}; \
40  template<> std::vector<std::string> common::EnumIface<enumType>::names = \
41  {__VA_ARGS__};
42 
45  template<typename T>
46  class EnumIface
47  {
50  public: static T Begin()
51  {
52  return range[0];
53  }
54 
57  public: static T End()
58  {
59  return range[1];
60  }
61 
67  static std::string Str(T const &_e)
68  {
69  if (_e < names.size())
70  return names[_e];
71  else
72  return "";
73  }
74 
80  static void Set(T &_e, const std::string &_str)
81  {
82  static auto begin = std::begin(names);
83  static auto end = std::end(names);
84 
85  auto find = std::find(begin, end, _str);
86  if (find != end)
87  {
88  _e = static_cast<T>(std::distance(begin, find));
89  }
90  }
91 
94  public: static T range[2];
95 
99  public: static std::vector<std::string> names;
100  };
101 
130  template<typename Enum>
131  class EnumIterator
132  : std::iterator<std::bidirectional_iterator_tag, Enum>
133  {
135  public: EnumIterator() : c(this->End())
136  {
137  }
138 
141  public: EnumIterator(const Enum _c) : c(_c)
142  {
143  GZ_ASSERT(this->c >= this->Begin() && this->c <= this->End(),
144  "Invalid enum value in EnumIterator constructor");
145  }
146 
149  public: EnumIterator &operator=(const Enum _c)
150  {
151  GZ_ASSERT(_c >= this->Begin() && _c <= this->End(),
152  "Invalid operator= value in EnumIterator");
153  this->c = _c;
154  return *this;
155  }
156 
159  public: static Enum Begin()
160  {
161  return EnumIface<Enum>::Begin();
162  }
163 
166  public: static Enum End()
167  {
168  return EnumIface<Enum>::End();
169  }
170 
173  public: EnumIterator &operator++()
174  {
175  GZ_ASSERT(this->c != this->End(), "Incrementing past end of enum");
176  this->c = static_cast<Enum>(this->c + 1);
177  return *this;
178  }
179 
182  public: EnumIterator operator++(const int)
183  {
184  GZ_ASSERT(this->c != this->End(), "Incrementing past end of enum");
185  EnumIterator cpy(*this);
186  ++*this;
187  return cpy;
188  }
189 
192  public: EnumIterator &operator--()
193  {
194  GZ_ASSERT(this->c != this->Begin(), "decrementing beyond begin?");
195  this->c = static_cast<Enum>(this->c - 1);
196  return *this;
197  }
198 
201  public: EnumIterator operator--(const int)
202  {
203  GZ_ASSERT(this->c != this->Begin(), "Decrementing beyond beginning.");
204  EnumIterator cpy(*this);
205  --*this;
206  return cpy;
207  }
208 
211  public: Enum operator*() const
212  {
213  GZ_ASSERT(this->c != this->End(), "Cannot dereference end iterator");
214  return c;
215  }
216 
219  public: Enum Value() const
220  {
221  return this->c;
222  }
223 
227  private: Enum c;
228  };
229 
234  template<typename Enum>
235  bool operator==(EnumIterator<Enum> _e1, EnumIterator<Enum> _e2)
236  {
237  return _e1.Value() == _e2.Value();
238  }
239 
244  template<typename Enum>
245  bool operator!=(EnumIterator<Enum> _e1, EnumIterator<Enum> _e2)
246  {
247  return !(_e1 == _e2);
248  }
249  }
250 }
251 #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.