Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

103 Zeilen
2.4 KiB

  1. #pragma once
  2. #include <limits>
  3. #include <type_traits>
  4. #include <initializer_list>
  5. namespace utl
  6. {
  7. template<class TEnum, class TBase>
  8. struct op_flag_convert_none
  9. {
  10. static inline TBase to_base(const TEnum e)
  11. { return static_cast<TBase>(e); }
  12. };
  13. template<class TEnum, class TBase>
  14. struct op_flag_convert_shift
  15. {
  16. static inline TBase to_base(const TEnum e)
  17. { return static_cast<TBase>(1 << static_cast<int>(e)); }
  18. };
  19. template<
  20. class TEnum,
  21. class TBase = typename std::underlying_type<TEnum>::type,
  22. class Op = op_flag_convert_none<TEnum, TBase>>
  23. struct flags
  24. {
  25. public:
  26. TBase value;
  27. public:
  28. inline bool is_set(TEnum e) const
  29. { return static_cast<bool>(value & Op::to_base(e)); }
  30. inline void set(TEnum e)
  31. { value = static_cast<TBase>(value | Op::to_base(e)); }
  32. inline void clear(TEnum e)
  33. { value = static_cast<TBase>(value & ~Op::to_base(e)); }
  34. inline void reset()
  35. { value = 0; }
  36. public:
  37. TBase operator()() const
  38. { return value; }
  39. operator bool() const
  40. { return static_cast<bool>(value); }
  41. bool operator[](TEnum e) const
  42. { return is_set(e); }
  43. public:
  44. flags() :
  45. value(0)
  46. { }
  47. explicit flags(TBase v) :
  48. value(v)
  49. { }
  50. flags(TEnum e) :
  51. value(Op::to_base(e))
  52. { }
  53. flags(const flags& other) :
  54. value(other.value)
  55. { }
  56. flags(std::initializer_list<TEnum> list) :
  57. flags()
  58. {
  59. for (auto& e : list)
  60. set(e);
  61. }
  62. public:
  63. static inline const flags& empty()
  64. {
  65. static const flags value(0);
  66. return value;
  67. }
  68. static inline const flags& all()
  69. {
  70. static const flags value(std::numeric_limits<TBase>::max());
  71. return value;
  72. }
  73. };
  74. template<
  75. class TEnum,
  76. class TBase = typename std::underlying_type<TEnum>::type>
  77. using shifted_flags = flags<TEnum, TBase, op_flag_convert_shift<TEnum, TBase>>;
  78. template<
  79. class TEnum,
  80. class TBase = typename std::underlying_type<TEnum>::type>
  81. using simple_flags = flags<TEnum, TBase, op_flag_convert_none<TEnum, TBase>>;
  82. }