Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

111 рядки
2.7 KiB

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