You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
3.1 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2017 CERN
  5. * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
  6. * @author Maciej Suminski <maciej.suminski@cern.ch>
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 3
  11. * of the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License along
  19. * with this program. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. #ifndef ENUM_VECTOR_H
  22. #define ENUM_VECTOR_H
  23. #include <iterator>
  24. #include <type_traits>
  25. /**
  26. * Macro to create const vectors containing enum values to enable easy iteration.
  27. *
  28. * @warning Do not use in new code. Use the #DEFINE_ENUM_CLASS_WITH_ITERATOR and
  29. * #DECLARE_ENUM_CLASS_ITERATOR macros instead (unless they don't work ;) ).
  30. *
  31. * Usage:
  32. * [header]
  33. * A {
  34. * DEFINE_ENUM_VECTOR( COLOR, { RED, GREEN, BLUE } )
  35. * };
  36. *
  37. * [source]
  38. * for( COLOR color : COLOR_vector ) {
  39. * // do sth with color
  40. * }
  41. *
  42. * DECLARE_ENUM_VECTOR( COLORS );
  43. */
  44. #define DEFINE_ENUM_VECTOR( enumName, ... ) \
  45. enum enumName __VA_ARGS__; \
  46. static constexpr enumName enumName##_vector[] = __VA_ARGS__;
  47. #define DECLARE_ENUM_VECTOR( className, enumName ) \
  48. constexpr className::enumName className::enumName##_vector[];
  49. /**
  50. * Macro to create const vectors containing enum class values to enable easy iteration.
  51. *
  52. * Usage:
  53. * [header]
  54. * A {
  55. * DEFINE_ENUM_CLASS_WITH_ITERATOR( COLOR, RED, GREEN, BLUE )
  56. * };
  57. *
  58. * [source]
  59. * for( COLOR color : COLOR_ITERATOR() ) {
  60. * // do sth with color
  61. * }
  62. */
  63. #define DEFINE_ENUM_CLASS_WITH_ITERATOR( enumName, beginVal, ... ) \
  64. enum class enumName : int { beginVal, __VA_ARGS__, _ENUM_END }; \
  65. typedef ENUM_ITERATOR<enumName, enumName::beginVal, enumName::_ENUM_END> enumName##_ITERATOR;
  66. template <typename T, T beginVal, T endVal>
  67. class ENUM_ITERATOR
  68. {
  69. typedef typename std::underlying_type<T>::type val_t;
  70. int val;
  71. public:
  72. using value_type = T;
  73. using difference_type = std::ptrdiff_t;
  74. using pointer = T*;
  75. using reference = T&;
  76. using iterator_category = std::input_iterator_tag;
  77. ENUM_ITERATOR( const T& f ) : val( static_cast<val_t>( f ) ) {}
  78. ENUM_ITERATOR() : val( static_cast<val_t>( beginVal ) ) {}
  79. ENUM_ITERATOR operator++()
  80. {
  81. val++;
  82. return *this;
  83. }
  84. T operator*() { return static_cast<T>( val ); }
  85. ENUM_ITERATOR begin() { return *this; }
  86. ENUM_ITERATOR end() { return ENUM_ITERATOR( endVal ); }
  87. bool operator==( const ENUM_ITERATOR& aIt ) const { return val == aIt.val; }
  88. bool operator!=( const ENUM_ITERATOR& aIt ) const { return val != aIt.val; }
  89. };
  90. #endif /* ENUM_VECTOR_H */