}
}
+template <typename InputIter>
+constexpr unsigned long long calc_bitset_val(InputIter first, InputIter last) noexcept
+{
+ auto result = 0ULL;
+ for (; first != last; ++first) {
+ result |= 1ULL << static_cast<int>(*first);
+ }
+ return result;
+}
+
}
/**
*
* すべてのフラグがOFFの状態のFlagGroupクラスのインスタンスを生成する
*/
- FlagGroup() = default;
+ constexpr FlagGroup() = default;
/**
* @brief FlagGroupクラスのコンストラクタ
*
* @param il ONの状態で生成するフラグを指定した initializer_list
*/
- FlagGroup(std::initializer_list<FlagType> il)
+ constexpr FlagGroup(std::initializer_list<FlagType> il)
: FlagGroup(il.begin(), il.end())
{
}
*
* @param range 範囲を示すEnumRangeクラスのオブジェクト
*/
- FlagGroup(const EnumRange<FlagType> &range)
+ constexpr FlagGroup(const EnumRange<FlagType> &range)
: FlagGroup(range.begin(), range.end())
{
}
* 入力イテレータで指定した範囲のリストに含まれるフラグがON、
* それ以外のフラグがOFFの状態のFlagGroupクラスのインスタンスを生成する
*
+ * FLAG_TYPE_MAXがunsigned long longのビットサイズ以下の場合、
+ * unsigned long longの値を引数に取るstd::bitsetのconstexpr化された
+ * コンストラクタが使用できるので、FlagGroupクラスでも
+ * constexprコンストラクタとしてこちらを選択する。
+ *
+ * @tparam InputIter 入力イテレータの型
+ * @param first 範囲の開始位置を示す入力イテレータ
+ * @param last 範囲の終了位置を示す入力イテレータ
+ */
+ template <flag_group::FlagIter<FlagType> 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 <flag_group::FlagIter<FlagType> InputIter>
+ requires(FLAG_TYPE_MAX > sizeof(unsigned long long) * 8)
FlagGroup(InputIter first, InputIter last)
{
for (; first != last; ++first) {