From 439a7d5d7a1dbe4b3ce49ee94ba952128c8a8bcb Mon Sep 17 00:00:00 2001 From: Meik Jaeckle Date: Fri, 23 Feb 2024 19:00:19 +0100 Subject: [PATCH 1/4] - Added method that allows to create a flag_set out of an integral value. --- include/type_safe/flag_set.hpp | 20 ++++++++++++++++++++ test/flag_set.cpp | 17 +++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/include/type_safe/flag_set.hpp b/include/type_safe/flag_set.hpp index 0d4ce705..e2cb2590 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: + /// \returns a flag_set based on the given integer value. + /// \requires `T` must be an unsigned integer type with number of bits <= internal used bit size. + template + static constexpr flag_set from_int(T intVal) + { + static_assert(std::is_unsigned::value + && sizeof(T) * CHAR_BIT >= flag_set_traits::size(), + "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,10 @@ class flag_set } private: + using int_type = typename detail::flag_set_impl::int_type; + 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 7a2f380a..e73a5460 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); From 3e48a43ed02156d3e023eda77a3fdf1f6e3e511d Mon Sep 17 00:00:00 2001 From: Meik Jaeckle Date: Sat, 24 Feb 2024 14:53:13 +0100 Subject: [PATCH 2/4] - Fixed static_assert guard, comparing the type size --- include/type_safe/flag_set.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/type_safe/flag_set.hpp b/include/type_safe/flag_set.hpp index e2cb2590..3686b297 100644 --- a/include/type_safe/flag_set.hpp +++ b/include/type_safe/flag_set.hpp @@ -427,7 +427,7 @@ class flag_set static constexpr flag_set from_int(T intVal) { static_assert(std::is_unsigned::value - && sizeof(T) * CHAR_BIT >= flag_set_traits::size(), + && sizeof(T) <= sizeof(int_type), "invalid integer type, lossy conversion"); return flag_set(intVal); } From cb47e99346782893abe1d61d135d96ddaeea26ad Mon Sep 17 00:00:00 2001 From: Meik Jaeckle Date: Sat, 24 Feb 2024 21:10:05 +0100 Subject: [PATCH 3/4] - Introduced review comments: check for same type instead of size is less equal --- include/type_safe/flag_set.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/type_safe/flag_set.hpp b/include/type_safe/flag_set.hpp index 3686b297..b0e0f78b 100644 --- a/include/type_safe/flag_set.hpp +++ b/include/type_safe/flag_set.hpp @@ -421,14 +421,14 @@ 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 an unsigned integer type with number of bits <= internal used bit size. + /// \requires `T` must be of the same type as `int_type`. template static constexpr flag_set from_int(T intVal) { - static_assert(std::is_unsigned::value - && sizeof(T) <= sizeof(int_type), - "invalid integer type, lossy conversion"); + static_assert(std::is_same::value, "invalid integer type, lossy conversion"); return flag_set(intVal); } From 7566cc9112e40374e2db83cf9d5b135e9a781992 Mon Sep 17 00:00:00 2001 From: Meik Jaeckle Date: Sat, 24 Feb 2024 21:12:34 +0100 Subject: [PATCH 4/4] - Fixed build, forgot to removed duplicated type --- include/type_safe/flag_set.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/include/type_safe/flag_set.hpp b/include/type_safe/flag_set.hpp index b0e0f78b..25a2a28b 100644 --- a/include/type_safe/flag_set.hpp +++ b/include/type_safe/flag_set.hpp @@ -625,7 +625,6 @@ class flag_set } private: - using int_type = typename detail::flag_set_impl::int_type; explicit constexpr flag_set(int_type rawvalue) noexcept : flags_(detail::flag_set_impl::from_int(rawvalue)) {}