From ae6f797561cdfa438ebef1fbbf94d784d315e655 Mon Sep 17 00:00:00 2001 From: crupest Date: Wed, 1 Jan 2020 17:38:45 +0800 Subject: ... --- include/cru/common/base.hpp | 67 ++++++++++++++++++++++++++++++++++++++++++++ include/cru/common/event.hpp | 17 +++++++---- 2 files changed, 79 insertions(+), 5 deletions(-) (limited to 'include/cru/common') diff --git a/include/cru/common/base.hpp b/include/cru/common/base.hpp index 4264142d..d4f164bf 100644 --- a/include/cru/common/base.hpp +++ b/include/cru/common/base.hpp @@ -2,6 +2,7 @@ #include "pre_config.hpp" #include +#include #define CRU_UNUSED(entity) static_cast(entity); @@ -40,4 +41,70 @@ struct Interface { [[noreturn]] inline void UnreachableCode() { throw std::runtime_error("Unreachable code."); } + } // namespace cru + +template +struct enable_bitmask_operators : std::false_type {}; + +#define CRU_ENABLE_BITMASK_OPERATORS(enumname) \ + template <> \ + struct enable_bitmask_operators : std::true_type {}; + +template +auto operator|(Enum lhs, Enum rhs) + -> std::enable_if_t::value, Enum> { + using underlying = typename std::underlying_type::type; + return static_cast(static_cast(lhs) | + static_cast(rhs)); +} + +template +auto operator&(Enum lhs, Enum rhs) + -> std::enable_if_t::value, Enum> { + using underlying = typename std::underlying_type::type; + return static_cast(static_cast(lhs) & + static_cast(rhs)); +} + +template +auto operator^(Enum lhs, Enum rhs) + -> std::enable_if_t::value, Enum> { + using underlying = typename std::underlying_type::type; + return static_cast(static_cast(lhs) ^ + static_cast(rhs)); +} + +template +auto operator~(Enum rhs) + -> std::enable_if_t::value, Enum> { + using underlying = typename std::underlying_type::type; + return static_cast(~static_cast(rhs)); +} + +template +auto operator|=(Enum& lhs, Enum rhs) + -> std::enable_if_t::value, Enum&> { + using underlying = typename std::underlying_type::type; + lhs = static_cast(static_cast(lhs) | + static_cast(rhs)); + return lhs; +} + +template +auto operator&=(Enum& lhs, Enum rhs) + -> std::enable_if_t::value, Enum&> { + using underlying = typename std::underlying_type::type; + lhs = static_cast(static_cast(lhs) & + static_cast(rhs)); + return lhs; +} + +template +auto operator^=(Enum& lhs, Enum rhs) + -> std::enable_if_t::value, Enum&> { + using underlying = typename std::underlying_type::type; + lhs = static_cast(static_cast(lhs) ^ + static_cast(rhs)); + return lhs; +} diff --git a/include/cru/common/event.hpp b/include/cru/common/event.hpp index 33b2e3f6..55a00d7e 100644 --- a/include/cru/common/event.hpp +++ b/include/cru/common/event.hpp @@ -3,6 +3,7 @@ #include "self_resolvable.hpp" +#include #include #include #include @@ -99,7 +100,8 @@ struct IEvent { IEvent(IEvent&& other) = delete; IEvent& operator=(const IEvent& other) = delete; IEvent& operator=(IEvent&& other) = delete; - ~IEvent() = default; + ~IEvent() = default; // Note that user can't destroy a Event via IEvent. So + // destructor should be protected. public: virtual EventRevoker AddHandler(const EventHandler& handler) = 0; @@ -130,14 +132,16 @@ class Event : public details::EventBase, public IEvent { EventRevoker AddHandler(const EventHandler& handler) override { const auto token = current_token_++; - this->handler_data_list_.emplace_after(this->last_handler_iterator_ ,token, handler); + this->handler_data_list_.emplace_after(this->last_handler_iterator_, token, + handler); ++(this->last_handler_iterator_); return CreateRevoker(token); } EventRevoker AddHandler(EventHandler&& handler) override { const auto token = current_token_++; - this->handler_data_list_.emplace_after(this->last_handler_iterator_ ,token, std::move(handler)); + this->handler_data_list_.emplace_after(this->last_handler_iterator_, token, + std::move(handler)); ++(this->last_handler_iterator_); return CreateRevoker(token); } @@ -163,12 +167,15 @@ class Event : public details::EventBase, public IEvent { protected: void RemoveHandler(EventHandlerToken token) override { this->handler_data_list_.remove_if( - [token](const HandlerData& data) { return data.token == token; }); + [token](const HandlerData& data) { return data.token == token; }); } private: std::forward_list handler_data_list_{}; - typename std::forward_list::const_iterator last_handler_iterator_ = this->handler_data_list_.cbefore_begin(); // remember the last handler to make push back O(1) + typename std::forward_list< + HandlerData>::const_iterator last_handler_iterator_ = + this->handler_data_list_ + .cbefore_begin(); // remember the last handler to make push back O(1) EventHandlerToken current_token_ = 0; }; -- cgit v1.2.3