@@ -645,6 +645,39 @@ struct recv_buffer_result
645645 }
646646};
647647
648+ namespace detail
649+ {
650+ template <class T >
651+ constexpr T enum_bit_or (T a, T b) noexcept
652+ {
653+ static_assert (std::is_enum<T>::value, " must be enum" );
654+ using U = typename std::underlying_type<T>::type;
655+ return static_cast <T>(static_cast <U>(a) | static_cast <U>(b));
656+ }
657+ template <class T >
658+ constexpr T enum_bit_and (T a, T b) noexcept
659+ {
660+ static_assert (std::is_enum<T>::value, " must be enum" );
661+ using U = typename std::underlying_type<T>::type;
662+ return static_cast <T>(static_cast <U>(a) & static_cast <U>(b));
663+ }
664+ template <class T >
665+ constexpr T enum_bit_xor (T a, T b) noexcept
666+ {
667+ static_assert (std::is_enum<T>::value, " must be enum" );
668+ using U = typename std::underlying_type<T>::type;
669+ return static_cast <T>(static_cast <U>(a) ^ static_cast <U>(b));
670+ }
671+ template <class T >
672+ constexpr T enum_bit_not (T a) noexcept
673+ {
674+ static_assert (std::is_enum<T>::value, " must be enum" );
675+ using U = typename std::underlying_type<T>::type;
676+ return static_cast <T>(~static_cast <U>(a));
677+ }
678+ } // namespace detail
679+
680+ // partially satisfies named requirement BitmaskType
648681enum class send_flags : int
649682{
650683 none = 0 ,
@@ -654,10 +687,22 @@ enum class send_flags : int
654687
655688constexpr send_flags operator |(send_flags a, send_flags b) noexcept
656689{
657- return static_cast <send_flags>(static_cast <std::underlying_type<send_flags>::type>(a)
658- | static_cast <<std::underlying_type<send_flags>::type>(b));
690+ return detail::enum_bit_or (a, b);
691+ }
692+ constexpr send_flags operator &(send_flags a, send_flags b) noexcept
693+ {
694+ return detail::enum_bit_and (a, b);
695+ }
696+ constexpr send_flags operator ^(send_flags a, send_flags b) noexcept
697+ {
698+ return detail::enum_bit_xor (a, b);
699+ }
700+ constexpr send_flags operator ~(send_flags a) noexcept
701+ {
702+ return detail::enum_bit_not (a);
659703}
660704
705+ // partially satisfies named requirement BitmaskType
661706enum class recv_flags : int
662707{
663708 none = 0 ,
@@ -666,8 +711,21 @@ enum class recv_flags : int
666711
667712constexpr recv_flags operator |(recv_flags a, recv_flags b) noexcept
668713{
669- return static_cast <recv_flags>(static_cast <int >(a) | static_cast <int >(b));
714+ return detail::enum_bit_or (a, b);
715+ }
716+ constexpr recv_flags operator &(recv_flags a, recv_flags b) noexcept
717+ {
718+ return detail::enum_bit_and (a, b);
719+ }
720+ constexpr recv_flags operator ^(recv_flags a, recv_flags b) noexcept
721+ {
722+ return detail::enum_bit_xor (a, b);
670723}
724+ constexpr recv_flags operator ~(recv_flags a) noexcept
725+ {
726+ return detail::enum_bit_not (a);
727+ }
728+
671729
672730// mutable_buffer, const_buffer and buffer are based on
673731// the Networking TS specification, draft:
0 commit comments