From: Habu Date: Fri, 2 Jun 2023 10:56:40 +0000 (+0900) Subject: [Update] FlagGroupのコンストラクタのconstexpr化 X-Git-Tag: 3.0.0.85(Alpha)^2~25^2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=c49afd9a6706ed7da4ee0b1e6c43d2029b88fb72;p=hengbandforosx%2Fhengbandosx.git [Update] FlagGroupのコンストラクタのconstexpr化 FlagGroupクラスで保持するフラグ列挙値の最大値がunsigned long long型の ビットサイズ未満の場合、std::bitsetのunsigned long long型を引数に受け取 るconstexprコンストラクタを使用することでFlagGroupのコンストラクタも constexprにする。 --- diff --git a/src/util/flag-group.h b/src/util/flag-group.h index 4c7972917..e476f64bd 100644 --- a/src/util/flag-group.h +++ b/src/util/flag-group.h @@ -62,6 +62,16 @@ void write_bitset(const std::bitset &bs, Func wr_byte_func, size_t } } +template +constexpr unsigned long long calc_bitset_val(InputIter first, InputIter last) noexcept +{ + auto result = 0ULL; + for (; first != last; ++first) { + result |= 1ULL << static_cast(*first); + } + return result; +} + } /** @@ -94,7 +104,7 @@ public: * * すべてのフラグがOFFの状態のFlagGroupクラスのインスタンスを生成する */ - FlagGroup() = default; + constexpr FlagGroup() = default; /** * @brief FlagGroupクラスのコンストラクタ @@ -104,7 +114,7 @@ public: * * @param il ONの状態で生成するフラグを指定した initializer_list */ - FlagGroup(std::initializer_list il) + constexpr FlagGroup(std::initializer_list il) : FlagGroup(il.begin(), il.end()) { } @@ -117,7 +127,7 @@ public: * * @param range 範囲を示すEnumRangeクラスのオブジェクト */ - FlagGroup(const EnumRange &range) + constexpr FlagGroup(const EnumRange &range) : FlagGroup(range.begin(), range.end()) { } @@ -128,11 +138,42 @@ public: * 入力イテレータで指定した範囲のリストに含まれるフラグがON、 * それ以外のフラグがOFFの状態のFlagGroupクラスのインスタンスを生成する * + * FLAG_TYPE_MAXがunsigned long longのビットサイズ以下の場合、 + * unsigned long longの値を引数に取るstd::bitsetのconstexpr化された + * コンストラクタが使用できるので、FlagGroupクラスでも + * constexprコンストラクタとしてこちらを選択する。 + * + * @tparam InputIter 入力イテレータの型 + * @param first 範囲の開始位置を示す入力イテレータ + * @param last 範囲の終了位置を示す入力イテレータ + */ + template InputIter> + requires(FLAG_TYPE_MAX <= sizeof(unsigned long long) * 8) + constexpr FlagGroup(InputIter first, InputIter last) + : bs_(flag_group::detail::calc_bitset_val(first, last)) + { + } + + /** + * @brief FlagGroupクラスのコンストラクタ + * + * 入力イテレータで指定した範囲のリストに含まれるフラグがON、 + * それ以外のフラグがOFFの状態のFlagGroupクラスのインスタンスを生成する + * + * FLAG_TYPE_MAXがunsigned long longのビットサイズより大きい場合、 + * C++20の範囲ではstd::bitsetをconstexprコンストラクタで初期化することは + * できないため、constexprではない通常のコンストラクタとしてこちらを選択する。 + * + * @todo C++23以降であればstd::bitsetの多くのメンバ関数がconstepxr化されているので + * FLAG_TYPE_MAXがunsigned long longのビットサイズより大きくてもconstexpr化が + * 可能になると思われる。 + * * @tparam InputIter 入力イテレータの型 * @param first 範囲の開始位置を示す入力イテレータ * @param last 範囲の終了位置を示す入力イテレータ */ template InputIter> + requires(FLAG_TYPE_MAX > sizeof(unsigned long long) * 8) FlagGroup(InputIter first, InputIter last) { for (; first != last; ++first) {