mirror of
https://github.com/Neargye/magic_enum.git
synced 2026-01-09 23:34:23 +00:00
add bitwise_operators
This commit is contained in:
parent
cd01fa1ba4
commit
9a700b545d
4 changed files with 71 additions and 8 deletions
|
|
@ -118,7 +118,7 @@ enum Color { RED = 2, BLUE = 4, GREEN = 8 };
|
||||||
|
|
||||||
* Stream operator for enum
|
* Stream operator for enum
|
||||||
```cpp
|
```cpp
|
||||||
using namespace magic_enum::ops; // out-of-the-box stream operator for enums.
|
using namespace magic_enum::ostream_operators; // out-of-the-box ostream operators for enums.
|
||||||
Color color = Color::BLUE;
|
Color color = Color::BLUE;
|
||||||
std::cout << color << std::endl; // "BLUE"
|
std::cout << color << std::endl; // "BLUE"
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ int main() {
|
||||||
std::cout << "RED = " << color_integer << std::endl; // RED = -10
|
std::cout << "RED = " << color_integer << std::endl; // RED = -10
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace magic_enum::ops; // out-of-the-box stream operator for enums.
|
using namespace magic_enum::ostream_operators; // out-of-the-box ostream operator for enums.
|
||||||
// ostream operator for enum.
|
// ostream operator for enum.
|
||||||
std::cout << "Color: " << c1 << " " << c2 << " " << c3 << std::endl; // Color: RED BLUE GREEN
|
std::cout << "Color: " << c1 << " " << c2 << " " << c3 << std::endl; // Color: RED BLUE GREEN
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -368,11 +368,11 @@ template <typename E, typename D = detail::enable_if_enum_t<E>>
|
||||||
return entries;
|
return entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ops {
|
namespace ostream_operators {
|
||||||
|
|
||||||
template <class Char, class Traits, typename E, typename D = detail::enable_if_enum_t<E>>
|
template <class Char, class Traits, typename E, typename D = detail::enable_if_enum_t<E>>
|
||||||
std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os, E value) {
|
std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os, E value) {
|
||||||
static_assert(detail::check_enum_v<E, D>, "magic_enum::ops::operator<< requires enum type.");
|
static_assert(detail::check_enum_v<E, D>, "magic_enum::ostream_operators::operator<< requires enum type.");
|
||||||
|
|
||||||
if (auto name = detail::name_impl<D>(static_cast<int>(value)); !name.empty()) {
|
if (auto name = detail::name_impl<D>(static_cast<int>(value)); !name.empty()) {
|
||||||
for (auto c : name) {
|
for (auto c : name) {
|
||||||
|
|
@ -385,7 +385,7 @@ std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& o
|
||||||
|
|
||||||
template <class Char, class Traits, typename E, typename D = detail::enable_if_enum_t<E>>
|
template <class Char, class Traits, typename E, typename D = detail::enable_if_enum_t<E>>
|
||||||
std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os, std::optional<E> value) {
|
std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os, std::optional<E> value) {
|
||||||
static_assert(detail::check_enum_v<E, D>, "magic_enum::ops::operator<< requires enum type.");
|
static_assert(detail::check_enum_v<E, D>, "magic_enum::ostream_operators::operator<< requires enum type.");
|
||||||
|
|
||||||
if (value.has_value()) {
|
if (value.has_value()) {
|
||||||
if (auto name = detail::name_impl<D>(static_cast<int>(value.value())); !name.empty()) {
|
if (auto name = detail::name_impl<D>(static_cast<int>(value.value())); !name.empty()) {
|
||||||
|
|
@ -398,7 +398,67 @@ std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& o
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace magic_enum::ops
|
} // namespace magic_enum::ostream_operators
|
||||||
|
|
||||||
|
namespace bitwise_operators {
|
||||||
|
|
||||||
|
template <typename E, typename D = detail::enable_if_enum_t<E>>
|
||||||
|
constexpr E operator~(E rhs) {
|
||||||
|
static_assert(detail::check_enum_v<E, D>, "magic_enum::bitwise_operators::operator~ requires enum type.");
|
||||||
|
using U = std::underlying_type_t<D>;
|
||||||
|
|
||||||
|
return static_cast<E>(~static_cast<U>(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename E, typename D = detail::enable_if_enum_t<E>>
|
||||||
|
constexpr E operator|(E lhs, E rhs) {
|
||||||
|
static_assert(detail::check_enum_v<E, D>, "magic_enum::bitwise_operators::operator| requires enum type.");
|
||||||
|
using U = std::underlying_type_t<D>;
|
||||||
|
|
||||||
|
return static_cast<E>(static_cast<U>(lhs) | static_cast<U>(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename E, typename D = detail::enable_if_enum_t<E>>
|
||||||
|
constexpr E operator&(E lhs, E rhs) {
|
||||||
|
static_assert(detail::check_enum_v<E, D>, "magic_enum::bitwise_operators::operator& requires enum type.");
|
||||||
|
using U = std::underlying_type_t<D>;
|
||||||
|
|
||||||
|
return static_cast<E>(static_cast<U>(lhs) & static_cast<U>(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename E, typename D = detail::enable_if_enum_t<E>>
|
||||||
|
constexpr E operator^(E lhs, E rhs) {
|
||||||
|
static_assert(detail::check_enum_v<E, D>, "magic_enum::bitwise_operators::operator^ requires enum type.");
|
||||||
|
using U = std::underlying_type_t<D>;
|
||||||
|
|
||||||
|
return static_cast<E>(static_cast<U>(lhs) ^ static_cast<U>(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename E, typename D = detail::enable_if_enum_t<E>>
|
||||||
|
constexpr E& operator|=(E& lhs, E rhs) {
|
||||||
|
static_assert(detail::check_enum_v<E, D>, "magic_enum::bitwise_operators::operator|= requires enum type.");
|
||||||
|
using U = std::underlying_type_t<D>;
|
||||||
|
|
||||||
|
return lhs = static_cast<E>(static_cast<U>(lhs) | static_cast<U>(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename E, typename D = detail::enable_if_enum_t<E>>
|
||||||
|
constexpr E& operator&=(E& lhs, E rhs) {
|
||||||
|
static_assert(detail::check_enum_v<E, D>, "magic_enum::bitwise_operators::operator%= requires enum type.");
|
||||||
|
using U = std::underlying_type_t<D>;
|
||||||
|
|
||||||
|
return lhs = static_cast<E>(static_cast<U>(lhs) & static_cast<U>(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename E, typename D = detail::enable_if_enum_t<E>>
|
||||||
|
constexpr E& operator^=(E& lhs, E rhs) {
|
||||||
|
static_assert(detail::check_enum_v<E, D>, "magic_enum::bitwise_operators::operator^= requires enum type.");
|
||||||
|
using U = std::underlying_type_t<D>;
|
||||||
|
|
||||||
|
return lhs = static_cast<E>(static_cast<U>(lhs) ^ static_cast<U>(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace magic_enum::bitwise_operators
|
||||||
|
|
||||||
} // namespace magic_enum
|
} // namespace magic_enum
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -291,9 +291,9 @@ TEST_CASE("enum_entries") {
|
||||||
REQUIRE(s4 == std::array<std::pair<number, std::string_view>, 3>{{{number::one, "one"}, {number::two, "two"}, {number::three, "three"}}});
|
REQUIRE(s4 == std::array<std::pair<number, std::string_view>, 3>{{{number::one, "one"}, {number::two, "two"}, {number::three, "three"}}});
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("operator<<") {
|
TEST_CASE("ostream_operators") {
|
||||||
auto test_ostream = [](auto e, std::string_view name) {
|
auto test_ostream = [](auto e, std::string_view name) {
|
||||||
using namespace magic_enum::ops;
|
using namespace magic_enum::ostream_operators;
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << e;
|
ss << e;
|
||||||
REQUIRE(ss.str() == name);
|
REQUIRE(ss.str() == name);
|
||||||
|
|
@ -323,6 +323,9 @@ TEST_CASE("operator<<") {
|
||||||
test_ostream(static_cast<number>(0), "");
|
test_ostream(static_cast<number>(0), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("bitwise_operators") {
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("type_traits") {
|
TEST_CASE("type_traits") {
|
||||||
REQUIRE_FALSE(magic_enum::is_unscoped_enum_v<Color>);
|
REQUIRE_FALSE(magic_enum::is_unscoped_enum_v<Color>);
|
||||||
REQUIRE_FALSE(magic_enum::is_unscoped_enum_v<Numbers>);
|
REQUIRE_FALSE(magic_enum::is_unscoped_enum_v<Numbers>);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue