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  {
40  #define GZ_ENUM(enumType, begin, end, ...) \
41  template<> GZ_COMMON_VISIBLE enumType \
42  common::EnumIface<enumType>::range[] = {begin, end}; \
43  template<> GZ_COMMON_VISIBLE \
44  std::vector<std::string> common::EnumIface<enumType>::names = {__VA_ARGS__};
45 
56 #ifndef _MSC_VER
57  #define GZ_ENUM_VISIBILITY(visibility, enumType, begin, end, ...) \
58  template<> visibility enumType \
59  common::EnumIface<enumType>::range[] = {begin, end}; \
60  template<> visibility std::vector<std::string> \
61  common::EnumIface<enumType>::names = {__VA_ARGS__};
62 #else
63  #define GZ_ENUM_VISIBILITY(visibility, enumType, begin, end, ...) \
64  template<> enumType \
65  common::EnumIface<enumType>::range[] = {begin, end}; \
66  template<> std::vector<std::string> \
67  common::EnumIface<enumType>::names = {__VA_ARGS__}; \
68  template class visibility common::EnumIface<enumType>;
69 #endif
70 
76 #ifndef _MSC_VER
77  #define GZ_ENUM_DECLARE(visibility, enumType)
78 #else
79  #define GZ_ENUM_DECLARE(visibility, enumType) \
80  template class visibility common::EnumIface<enumType>;
81 #endif
82 
83 #ifdef __clang__
84 #pragma clang diagnostic push
85 #pragma clang diagnostic ignored "-Wundefined-var-template"
86 #endif
87  template<typename T>
90  class EnumIface
91  {
94  public: static T Begin()
95  {
96  return range[0];
97  }
98 
101  public: static T End()
102  {
103  return range[1];
104  }
105 
111  static std::string Str(T const &_e)
112  {
113  if (static_cast<unsigned int>(_e) < names.size())
114  return names[static_cast<unsigned int>(_e)];
115  else
116  return "";
117  }
118 
124  static void Set(T &_e, const std::string &_str)
125  {
126  static auto begin = std::begin(names);
127  static auto end = std::end(names);
128 
129  auto find = std::find(begin, end, _str);
130  if (find != end)
131  {
132  _e = static_cast<T>(std::distance(begin, find));
133  }
134  }
135 
138  public: static T range[2];
139 
143  public: static std::vector<std::string> names;
144  };
145 #ifdef __clang__
146 #pragma clang diagnostic pop
147 #endif
148 
178  template<typename Enum>
179  class EnumIterator
180  : std::iterator<std::bidirectional_iterator_tag, Enum>
181  {
183  public: EnumIterator() : c(this->End())
184  {
185  }
186 
189  // cppcheck-suppress noExplicitConstructor
190  public: EnumIterator(const Enum _c) : c(_c)
191  {
192  GZ_ASSERT(this->c >= this->Begin() && this->c <= this->End(),
193  "Invalid enum value in EnumIterator constructor");
194  }
195 
198  public: EnumIterator &operator=(const Enum _c)
199  {
200  GZ_ASSERT(_c >= this->Begin() && _c <= this->End(),
201  "Invalid operator= value in EnumIterator");
202  this->c = _c;
203  return *this;
204  }
205 
208  public: static Enum Begin()
209  {
210  return EnumIface<Enum>::Begin();
211  }
212 
215  public: static Enum End()
216  {
217  return EnumIface<Enum>::End();
218  }
219 
222  public: EnumIterator &operator++()
223  {
224  GZ_ASSERT(this->c != this->End(), "Incrementing past end of enum");
225  this->c = static_cast<Enum>(static_cast<int>(this->c) + 1);
226  return *this;
227  }
228 
231  public: EnumIterator operator++(const int)
232  {
233  GZ_ASSERT(this->c != this->End(), "Incrementing past end of enum");
234  EnumIterator cpy(*this);
235  ++*this;
236  return cpy;
237  }
238 
241  public: EnumIterator &operator--()
242  {
243  GZ_ASSERT(this->c != this->Begin(), "decrementing beyond begin?");
244  this->c = static_cast<Enum>(static_cast<int>(this->c) - 1);
245  return *this;
246  }
247 
250  public: EnumIterator operator--(const int)
251  {
252  GZ_ASSERT(this->c != this->Begin(), "Decrementing beyond beginning.");
253  EnumIterator cpy(*this);
254  --*this;
255  return cpy;
256  }
257 
260  public: Enum operator*() const
261  {
262  GZ_ASSERT(this->c != this->End(), "Cannot dereference end iterator");
263  return c;
264  }
265 
268  public: Enum Value() const
269  {
270  return this->c;
271  }
272 
276  private: Enum c;
277  };
278 
283  template<typename Enum>
284  bool operator==(EnumIterator<Enum> _e1, EnumIterator<Enum> _e2)
285  {
286  return _e1.Value() == _e2.Value();
287  }
288 
293  template<typename Enum>
294  bool operator!=(EnumIterator<Enum> _e1, EnumIterator<Enum> _e2)
295  {
296  return !(_e1 == _e2);
297  }
298  }
299 }
300 #endif
#define GZ_ASSERT(_expr, _msg)
This macro define the standard way of launching an exception inside gazebo.
Definition: Assert.hh:24
Forward declarations for the common classes.
Definition: Animation.hh:26
GAZEBO_VISIBLE void Set(common::Image &_img, const msgs::Image &_msg)
Convert a msgs::Image to a common::Image.
common
Definition: FuelModelDatabase.hh:37