#pragma once
/**
 * @file enum_flags.h
 * @brief 提供将枚举转换为位标志的宏
 *
 * 这个文件定义了一组宏，用于将枚举类型转换为支持位操作的标志类型。
 */

#include <type_traits>

/**
 * @def DEFINE_ENUM_FLAGS
 * @brief 为枚举类型定义位运算操作符
 * @param EnumType 要启用位标志功能的枚举类型名称
 *
 * 为指定的枚举类型定义位运算操作符(|, &, ^, ~, |=, &=, ^=)和辅助函数。
 * 使用此宏后，枚举类型可以作为位标志使用。
 */
#define DEFINE_ENUM_FLAGS(EnumType) \
	inline EnumType operator|(EnumType a, EnumType b) { \
		return static_cast<EnumType>(static_cast<std::underlying_type_t<EnumType>>(a) | \
			   static_cast<std::underlying_type_t<EnumType>>(b)); \
	} \
	inline EnumType operator&(EnumType a, EnumType b) { \
		return static_cast<EnumType>(static_cast<std::underlying_type_t<EnumType>>(a) & \
			   static_cast<std::underlying_type_t<EnumType>>(b)); \
	} \
	inline EnumType operator^(EnumType a, EnumType b) { \
		return static_cast<EnumType>(static_cast<std::underlying_type_t<EnumType>>(a) ^ \
			   static_cast<std::underlying_type_t<EnumType>>(b)); \
	} \
	inline EnumType operator~(EnumType a) { \
		return static_cast<EnumType>(~static_cast<std::underlying_type_t<EnumType>>(a)); \
	} \
	inline EnumType& operator|=(EnumType& a, EnumType b) { \
		return a = a | b; \
	} \
	inline EnumType& operator&=(EnumType& a, EnumType b) { \
		return a = a & b; \
	} \
	inline EnumType& operator^=(EnumType& a, EnumType b) { \
		return a = a ^ b; \
	} \
	inline bool has_flag(EnumType value, EnumType flag) { \
		return (static_cast<std::underlying_type_t<EnumType>>(value) & \
				static_cast<std::underlying_type_t<EnumType>>(flag)) == \
				static_cast<std::underlying_type_t<EnumType>>(flag); \
	} \
	inline bool has_any_flag(EnumType value, EnumType flags) { \
		return (static_cast<std::underlying_type_t<EnumType>>(value) & \
				static_cast<std::underlying_type_t<EnumType>>(flags)) != 0; \
	} \
	inline void set_flag(EnumType& value, EnumType flag) { \
		value |= flag; \
	} \
	inline void clear_flag(EnumType& value, EnumType flag) { \
		value &= ~flag; \
	}
