All Classes Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
enums/helpers.hpp
1 // The MIT License (MIT)
2 
3 // Copyright (c) 2012-2014 Danny Y., Rapptz
4 
5 // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 // this software and associated documentation files (the "Software"), to deal in
7 // the Software without restriction, including without limitation the rights to
8 // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 // the Software, and to permit persons to whom the Software is furnished to do so,
10 // subject to the following conditions:
11 
12 // The above copyright notice and this permission notice shall be included in all
13 // copies or substantial portions of the Software.
14 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 
22 #ifndef GEARS_ENUMS_HELPERS_HPP
23 #define GEARS_ENUMS_HELPERS_HPP
24 
25 #include <type_traits>
26 
27 namespace gears {
28 namespace enums {
29 namespace detail {
30 template<typename... Args>
31 struct are_enum : std::true_type {};
32 
33 template<typename T>
34 struct are_enum<T> : std::is_enum<T> {};
35 
36 template<typename T, typename U, typename... Args>
37 struct are_enum<T, U, Args...> : std::integral_constant<bool, std::is_enum<T>::value &&
38  std::is_enum<U>::value &&
39  are_enum<Args...>::value> {};
40 
41 template<typename... Args>
42 using EnableIfEnum = typename std::enable_if<are_enum<typename std::remove_reference<Args>::type...>::value, bool>::type;
43 } // detail
57 template<typename Enum, typename Underlying = typename std::underlying_type<Enum>::type, detail::EnableIfEnum<Enum> = true>
58 constexpr Underlying to_underlying(Enum x) noexcept {
59  return static_cast<Underlying>(x);
60 }
61 
63 template<typename Enum, detail::EnableIfEnum<Enum> = true>
64 constexpr Enum activate_flags(const Enum& flag) noexcept {
65  return flag;
66 }
67 
68 template<typename Enum, detail::EnableIfEnum<Enum> = true>
69 constexpr Enum activate_flags(const Enum& first, const Enum& second) noexcept {
70  return static_cast<Enum>(to_underlying(first) | to_underlying(second));
71 }
72 
85 template<typename Enum, typename... Enums, detail::EnableIfEnum<Enum, Enums...> = true>
86 constexpr Enum activate_flags(const Enum& first, const Enum& second, Enums&&... rest) noexcept {
87  return static_cast<Enum>(to_underlying(activate_flags(first, second)) | to_underlying(activate_flags(rest...)));
88 }
90 
101 template<typename Enum, typename... Enums, detail::EnableIfEnum<Enum, Enums...> = true>
102 inline Enum& set_flags(Enum& flags, Enums&&... args) noexcept {
103  return flags = activate_flags(flags, args...);
104 }
105 
116 template<typename Enum, typename... Enums, detail::EnableIfEnum<Enum, Enums...> = true>
117 inline Enum& remove_flags(Enum& flags, Enums&&... args) noexcept {
118  return flags = static_cast<Enum>(to_underlying(flags) & (~to_underlying(activate_flags(args...))));
119 }
120 
133 template<typename Enum, typename... Enums, detail::EnableIfEnum<Enum, Enums...> = true>
134 constexpr bool has_flags(const Enum& flags, Enums&&... args) noexcept {
135  return (to_underlying(flags) & to_underlying(activate_flags(args...))) == to_underlying(activate_flags(args...));
136 }
137 } // enums
138 } // gears
139 
140 #endif // GEARS_ENUMS_HELPERS_HPP