7 * @brief enum もしくは enum class の列挙値の範囲を扱うクラス
9 * @tparam EnumType 対象となる列挙型(enum もしくは enum class)
11 template <typename EnumType>
13 static_assert(std::is_enum_v<EnumType>);
17 * @brief 列挙値の範囲のイテレータクラス
21 // std::iterator_traits に対応するための定義
22 using difference_type = int;
23 using value_type = EnumType;
24 using iterator_concept = std::input_iterator_tag;
27 * @brief 引数で与えた列挙値を指すイテレータオブジェクトを生成する
29 * @param val イテレータオブジェクトが指す列挙値
31 constexpr iterator(EnumType val) noexcept
32 : index(std::underlying_type_t<EnumType>(val))
37 * @brief イテレータが指している列挙値を取得する
39 * @return イテレータが指している列挙値
41 constexpr EnumType operator*() const noexcept
43 return static_cast<EnumType>(index);
47 * @brief イテレータを前置インクリメントする
51 constexpr iterator &operator++() noexcept
58 * @brief イテレータを後置インクリメントする
62 constexpr iterator operator++(int) noexcept
70 * @brief 2つのイテレータが指している列挙値が等しいかどうか調べる
72 * @param other 比較対象となるイテレータ
73 * @return 2つのイテレータが指している列挙値が等しければ true、そうでなければ false
75 constexpr bool operator==(const iterator &other) const noexcept
77 return index == other.index;
81 //! 現在イテレータが指している列挙値の基底型における整数値
82 std::underlying_type_t<EnumType> index;
86 * @brief 引数で与えた範囲の EnumRange クラスのオブジェクトを生成する
87 * @details 生成する範囲はfirstからlastまで(lastを含む)。
88 * 範囲の最終値+1の列挙値が存在しない場合を考慮し、半開区間ではなく閉区間で範囲を指定する。
89 * 範囲のイテレーションは基底型の整数値をインクリメントする事によって行うので、
90 * first から last までの間の整数値が飛んでいる場合、その部分は具体的な定義の無い列挙値がイテレートされる。
91 * @param first 範囲の最初となる列挙値
92 * @param last 範囲の最後となる列挙値(lastも含む)
94 constexpr EnumRange(EnumType first, EnumType last) noexcept
96 , end_val(static_cast<EnumType>(std::underlying_type_t<EnumType>(last) + 1))
101 * @brief 範囲の最初の列挙値を指すイテレータを取得する
103 * @return 範囲の最初の列挙値を指すイテレータ
105 constexpr iterator begin() const noexcept
107 return iterator(begin_val);
111 * @brief 範囲の最後の列挙値の次の値を指すイテレータを取得する
113 * @return 範囲の最後の列挙値の次の値を指すイテレータ
115 constexpr iterator end() const noexcept
117 return iterator(end_val);
121 * @brief 範囲に含まれる列挙値の種類数を取得する
123 * @return 範囲に含まれる列挙値の種類数
125 constexpr std::size_t size() const noexcept
127 return static_cast<std::size_t>(end_val) - static_cast<std::size_t>(begin_val);