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"
25
26namespace 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
89 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
common
Definition FuelModelDatabase.hh:37
GAZEBO_VISIBLE void Set(common::Image &_img, const msgs::Image &_msg)
Convert a msgs::Image to a common::Image.
Forward declarations for the common classes.
Definition Animation.hh:27