diff --git a/include/type_safe/flag_set.hpp b/include/type_safe/flag_set.hpp index 0d4ce70..25a2a28 100644 --- a/include/type_safe/flag_set.hpp +++ b/include/type_safe/flag_set.hpp @@ -115,6 +115,11 @@ namespace detail return flag_set_impl(int_type(0)); } + static constexpr flag_set_impl from_int(int_type intVal) + { + return flag_set_impl(int_type(intVal)); + } + explicit constexpr flag_set_impl(const Enum& e) : bits_(mask(e)) {} template explicit constexpr flag_set_impl(const flag_set_impl& other) @@ -416,6 +421,17 @@ class flag_set static_assert(flag_set_traits::value, "invalid enum for flag_set"); public: + using int_type = typename detail::flag_set_impl::int_type; + + /// \returns a flag_set based on the given integer value. + /// \requires `T` must be of the same type as `int_type`. + template + static constexpr flag_set from_int(T intVal) + { + static_assert(std::is_same::value, "invalid integer type, lossy conversion"); + return flag_set(intVal); + } + //=== constructors/assignment ===// /// \effects Creates a set where all flags are set to `0`. /// \group ctor_null @@ -609,6 +625,9 @@ class flag_set } private: + explicit constexpr flag_set(int_type rawvalue) noexcept : flags_(detail::flag_set_impl::from_int(rawvalue)) + {} + detail::flag_set_impl flags_; friend detail::get_flag_set_impl; diff --git a/test/flag_set.cpp b/test/flag_set.cpp index 7a2f380..e73a546 100644 --- a/test/flag_set.cpp +++ b/test/flag_set.cpp @@ -153,6 +153,23 @@ TEST_CASE("flag_set") b = test_flags::c; check_set(b, false, false, true); } + SECTION("from_int") + { + set a = set::from_int(0b000); + check_set(a, false, false, false); + + a = set::from_int(0b001); + check_set(a, true, false, false); + + a = set::from_int(0b010); + check_set(a, false, true, false); + + a = set::from_int(0b100); + check_set(a, false, false, true); + + a = set::from_int(0b111); + check_set(a, true, true, true); + } SECTION("set") { s.set(test_flags::a);