Improved enum flags operators and tests

This commit is contained in:
Gudmundur Adalsteinsson 2019-05-09 22:33:49 +00:00
parent 9a60ad3fc8
commit 99d98dd217
2 changed files with 82 additions and 4 deletions

View File

@ -46,7 +46,27 @@ TEST_CASE("socket swap", "[socket]")
using std::swap; using std::swap;
swap(socket1, socket2); swap(socket1, socket2);
} }
TEST_CASE("rass", "[socket]")
TEST_CASE("socket flags", "[socket]")
{
CHECK((zmq::recv_flags::dontwait | zmq::recv_flags::none)
== static_cast<zmq::recv_flags>(ZMQ_DONTWAIT | 0));
CHECK((zmq::recv_flags::dontwait & zmq::recv_flags::none)
== static_cast<zmq::recv_flags>(ZMQ_DONTWAIT & 0));
CHECK((zmq::recv_flags::dontwait ^ zmq::recv_flags::none)
== static_cast<zmq::recv_flags>(ZMQ_DONTWAIT ^ 0));
CHECK(~zmq::recv_flags::dontwait == static_cast<zmq::recv_flags>(~ZMQ_DONTWAIT));
CHECK((zmq::send_flags::dontwait | zmq::send_flags::sndmore)
== static_cast<zmq::send_flags>(ZMQ_DONTWAIT | ZMQ_SNDMORE));
CHECK((zmq::send_flags::dontwait & zmq::send_flags::sndmore)
== static_cast<zmq::send_flags>(ZMQ_DONTWAIT & ZMQ_SNDMORE));
CHECK((zmq::send_flags::dontwait ^ zmq::send_flags::sndmore)
== static_cast<zmq::send_flags>(ZMQ_DONTWAIT ^ ZMQ_SNDMORE));
CHECK(~zmq::send_flags::dontwait == static_cast<zmq::send_flags>(~ZMQ_DONTWAIT));
}
TEST_CASE("socket readme example", "[socket]")
{ {
zmq::context_t ctx; zmq::context_t ctx;
zmq::socket_t sock(ctx, zmq::socket_type::push); zmq::socket_t sock(ctx, zmq::socket_type::push);

64
zmq.hpp
View File

@ -645,6 +645,39 @@ struct recv_buffer_result
} }
}; };
namespace detail
{
template<class T>
constexpr T enum_bit_or(T a, T b) noexcept
{
static_assert(std::is_enum<T>::value, "must be enum");
using U = typename std::underlying_type<T>::type;
return static_cast<T>(static_cast<U>(a) | static_cast<U>(b));
}
template<class T>
constexpr T enum_bit_and(T a, T b) noexcept
{
static_assert(std::is_enum<T>::value, "must be enum");
using U = typename std::underlying_type<T>::type;
return static_cast<T>(static_cast<U>(a) & static_cast<U>(b));
}
template<class T>
constexpr T enum_bit_xor(T a, T b) noexcept
{
static_assert(std::is_enum<T>::value, "must be enum");
using U = typename std::underlying_type<T>::type;
return static_cast<T>(static_cast<U>(a) ^ static_cast<U>(b));
}
template<class T>
constexpr T enum_bit_not(T a) noexcept
{
static_assert(std::is_enum<T>::value, "must be enum");
using U = typename std::underlying_type<T>::type;
return static_cast<T>(~static_cast<U>(a));
}
} // namespace detail
// partially satisfies named requirement BitmaskType
enum class send_flags : int enum class send_flags : int
{ {
none = 0, none = 0,
@ -654,10 +687,22 @@ enum class send_flags : int
constexpr send_flags operator|(send_flags a, send_flags b) noexcept constexpr send_flags operator|(send_flags a, send_flags b) noexcept
{ {
return static_cast<send_flags>(static_cast<std::underlying_type<send_flags>::type>(a) return detail::enum_bit_or(a, b);
| static_cast<<std::underlying_type<send_flags>::type>(b)); }
constexpr send_flags operator&(send_flags a, send_flags b) noexcept
{
return detail::enum_bit_and(a, b);
}
constexpr send_flags operator^(send_flags a, send_flags b) noexcept
{
return detail::enum_bit_xor(a, b);
}
constexpr send_flags operator~(send_flags a) noexcept
{
return detail::enum_bit_not(a);
} }
// partially satisfies named requirement BitmaskType
enum class recv_flags : int enum class recv_flags : int
{ {
none = 0, none = 0,
@ -666,8 +711,21 @@ enum class recv_flags : int
constexpr recv_flags operator|(recv_flags a, recv_flags b) noexcept constexpr recv_flags operator|(recv_flags a, recv_flags b) noexcept
{ {
return static_cast<recv_flags>(static_cast<int>(a) | static_cast<int>(b)); return detail::enum_bit_or(a, b);
} }
constexpr recv_flags operator&(recv_flags a, recv_flags b) noexcept
{
return detail::enum_bit_and(a, b);
}
constexpr recv_flags operator^(recv_flags a, recv_flags b) noexcept
{
return detail::enum_bit_xor(a, b);
}
constexpr recv_flags operator~(recv_flags a) noexcept
{
return detail::enum_bit_not(a);
}
// mutable_buffer, const_buffer and buffer are based on // mutable_buffer, const_buffer and buffer are based on
// the Networking TS specification, draft: // the Networking TS specification, draft: