No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 

197 líneas
5.5 KiB

  1. #pragma once
  2. #include "flags.h"
  3. namespace cppcore
  4. {
  5. namespace __impl
  6. {
  7. /* op_flag_convert_none */
  8. template<class T_enum, class T_base>
  9. T_base op_flag_convert_none<T_enum, T_base>
  10. ::to_base(const T_enum& e)
  11. { return static_cast<T_base>(e); }
  12. template<class T_enum, class T_base>
  13. T_enum op_flag_convert_none<T_enum, T_base>
  14. ::from_index(const ssize_t& index)
  15. { return static_cast<T_enum>(1 << index); }
  16. /* op_flag_convert_shift */
  17. template<class T_enum, class T_base>
  18. T_base op_flag_convert_shift<T_enum, T_base>
  19. ::to_base(const T_enum& e)
  20. { return static_cast<T_base>(1 << static_cast<int>(e)); }
  21. template<class T_enum, class T_base>
  22. T_enum op_flag_convert_shift<T_enum, T_base>
  23. ::from_index(const ssize_t& index)
  24. { return static_cast<T_enum>(index); }
  25. }
  26. /* flags::iterator */
  27. template<class T_enum, class T_base, class T_op>
  28. flags<T_enum, T_base, T_op>::iterator
  29. ::iterator(const base_type& base, bool is_end)
  30. : _base(base)
  31. , _pos (is_end ? bit_count : -1)
  32. { next(); }
  33. template<class T_enum, class T_base, class T_op>
  34. bool flags<T_enum, T_base, T_op>::iterator
  35. ::operator==(const iterator& other) const
  36. { return _base == other._base && _pos == other._pos; }
  37. template<class T_enum, class T_base, class T_op>
  38. bool flags<T_enum, T_base, T_op>::iterator
  39. ::operator!=(const iterator& other) const
  40. { return _base != other._base || _pos != other._pos; }
  41. template<class T_enum, class T_base, class T_op>
  42. T_enum flags<T_enum, T_base, T_op>::iterator
  43. ::operator*() const
  44. {
  45. assert(_pos < bit_count);
  46. return op_type::from_index(_pos);
  47. }
  48. template<class T_enum, class T_base, class T_op>
  49. typename flags<T_enum, T_base, T_op>::iterator&
  50. flags<T_enum, T_base, T_op>::iterator
  51. ::operator++()
  52. {
  53. next();
  54. return *this;
  55. }
  56. template<class T_enum, class T_base, class T_op>
  57. typename flags<T_enum, T_base, T_op>::iterator
  58. flags<T_enum, T_base, T_op>::iterator
  59. ::operator++(int)
  60. {
  61. auto ret = *this;
  62. next();
  63. return ret;
  64. }
  65. template<class T_enum, class T_base, class T_op>
  66. void flags<T_enum, T_base, T_op>::iterator
  67. ::next()
  68. {
  69. if (_pos >= bit_count)
  70. return;
  71. do
  72. {
  73. ++_pos;
  74. } while(_pos < bit_count && !static_cast<bool>(_base & (1 << _pos)));
  75. }
  76. /* flags */
  77. template<class T_enum, class T_base, class T_op>
  78. flags<T_enum, T_base, T_op>
  79. ::flags()
  80. : value(0)
  81. { }
  82. template<class T_enum, class T_base, class T_op>
  83. flags<T_enum, T_base, T_op>
  84. ::flags(base_type v)
  85. : value(v)
  86. { }
  87. template<class T_enum, class T_base, class T_op>
  88. flags<T_enum, T_base, T_op>
  89. ::flags(enum_type e)
  90. : value(T_op::to_base(e))
  91. { }
  92. template<class T_enum, class T_base, class T_op>
  93. flags<T_enum, T_base, T_op>
  94. ::flags(const flags& other)
  95. : value(other.value)
  96. { }
  97. template<class T_enum, class T_base, class T_op>
  98. flags<T_enum, T_base, T_op>
  99. ::flags(std::initializer_list<enum_type> list)
  100. : flags()
  101. {
  102. for (auto& e : list)
  103. set(e);
  104. }
  105. template<class T_enum, class T_base, class T_op>
  106. auto flags<T_enum, T_base, T_op>
  107. ::begin() const
  108. { return iterator(value, false); }
  109. template<class T_enum, class T_base, class T_op>
  110. auto flags<T_enum, T_base, T_op>
  111. ::end() const
  112. { return iterator(value, true); }
  113. template<class T_enum, class T_base, class T_op>
  114. bool flags<T_enum, T_base, T_op>
  115. ::is_set(enum_type e) const
  116. { return static_cast<bool>(value & op_type::to_base(e)); }
  117. template<class T_enum, class T_base, class T_op>
  118. void flags<T_enum, T_base, T_op>
  119. ::set(enum_type e)
  120. { value = static_cast<base_type>(value | op_type::to_base(e)); }
  121. template<class T_enum, class T_base, class T_op>
  122. void flags<T_enum, T_base, T_op>
  123. ::clear(enum_type e)
  124. { value = static_cast<base_type>(value & ~op_type::to_base(e)); }
  125. template<class T_enum, class T_base, class T_op>
  126. void flags<T_enum, T_base, T_op>
  127. ::reset()
  128. { value = 0; }
  129. template<class T_enum, class T_base, class T_op>
  130. T_base flags<T_enum, T_base, T_op>
  131. ::operator()() const
  132. { return value; }
  133. template<class T_enum, class T_base, class T_op>
  134. flags<T_enum, T_base, T_op>
  135. ::operator base_type() const
  136. { return static_cast<base_type>(value); }
  137. template<class T_enum, class T_base, class T_op>
  138. flags<T_enum, T_base, T_op>
  139. ::operator bool() const
  140. { return static_cast<bool>(value); }
  141. template<class T_enum, class T_base, class T_op>
  142. bool flags<T_enum, T_base, T_op>
  143. ::operator[](enum_type e) const
  144. { return is_set(e); }
  145. template<class T_enum, class T_base, class T_op>
  146. const flags<T_enum, T_base, T_op>& flags<T_enum, T_base, T_op>
  147. ::empty()
  148. {
  149. const flags value(0);
  150. return value;
  151. }
  152. template<class T_enum, class T_base, class T_op>
  153. const flags<T_enum, T_base, T_op>& flags<T_enum, T_base, T_op>
  154. ::all()
  155. {
  156. const flags value(std::numeric_limits<base_type>::max());
  157. return value;
  158. }
  159. }