QT6 源(33):枚举类的源码,不要使用类 QFlag,它是辅助重要类 QFlags 的,和宏定义 Q_DECLARE_TYPEINFO(A,B),Q_DECLARE_FLAGS(A,B)

(1)本文所有内容来自于头文件 qflags.h ,整合了官方的注释

//The QFlag class is a helper data type for QFlags.
//它等同于一个普通的int,除了函数重载和类型转换方面。
//你永远不需要在你的应用程序中使用这个类。
//It is equivalent to a plain int,
//except with respect to function overloading and type conversions.
//You should never need to use this class in your applications.
class QFlag
{
    int i;
public:
    constexpr inline Q_IMPLICIT //本类的构造函数
    QFlag(int value) noexcept : i(value) {}

    //说明本类可自动转换为 int 类型,枚举类的本质,其实还是 int 类型
    constexpr inline Q_IMPLICIT //类型转换运算符函数
    operator int() const noexcept { return i; }

#if !defined(Q_CC_MSVC) //经验证,本 QT 确实没有定义此宏 Q_CC_MSVC。本 #if有效
    // Microsoft Visual Studio has buggy有小错的 behavior
    // when it comes to unsigned enums:
    // even if the enum is unsigned, the enum tags are always signed
    //当涉及到无符号枚举时,Microsoft VisualStudio有错误的行为:
    //即使枚举是未签名的,枚举标记始终是签名的
#  if !defined(__LP64__) && !defined(Q_CLANG_QDOC) //彩色,有效
    constexpr inline Q_IMPLICIT QFlag( long  value) noexcept
        : i(int(value)) {}  // 依然是构造函数

    constexpr inline Q_IMPLICIT QFlag(ulong  value) noexcept
        : i(int(long(value))) {}
#  endif

    constexpr inline Q_IMPLICIT QFlag(uint   value) noexcept
        : i(int(value)) {}  //这里其实是构成了构造函数的重载

    constexpr inline Q_IMPLICIT QFlag(short  value) noexcept
        : i(int(value)) {}

    constexpr inline Q_IMPLICIT QFlag(ushort value) noexcept
        : i(int(uint(value))) {}

    constexpr inline Q_IMPLICIT operator uint() const noexcept
    { return uint(i); }  //类型转换运算符函数,转换为无符号 int
#endif // #if !defined(Q_CC_MSVC)
};     //此宏是为了描述本新类型的存储特性
Q_DECLARE_TYPEINFO(QFlag, Q_PRIMITIVE_TYPE);
/* 相当于为模板类型 QTypeInfo 特化出了一个具体类型,描述本 QFlag 的存储特性
template<>
class QTypeInfo<QFlag> //Q_PRIMITIVE_TYPE 用于实例化本新类型中的数据成员
*/

(2)宏定义 Q_DECLARE_TYPEINFO(TYPE, FLAGS)

/*
   Specialize a specific type with:

     Q_DECLARE_TYPEINFO(type, flags);

   where 'type' is the name of the type to specialize and 'flags' is
   logically-OR'ed combination of the flags below.
*/
/* TYPEINFO flags */
enum {
    Q_COMPLEX_TYPE = 0,
    Q_PRIMITIVE_TYPE = 0x1,
    Q_RELOCATABLE_TYPE = 0x2,
    Q_MOVABLE_TYPE = 0x2,
    Q_DUMMY_TYPE = 0x4,
};

#define Q_DECLARE_TYPEINFO_BODY(TYPE, FLAGS) \
class QTypeInfo<TYPE > \
{ \
public: \
    enum { \
        isComplex = (((FLAGS) & Q_PRIMITIVE_TYPE) == 0) && !std::is_trivial_v<TYPE>, \
        isRelocatable = !isComplex || ((FLAGS) & Q_RELOCATABLE_TYPE) || qIsRelocatable<TYPE>, \
        isPointer = false, \
        isIntegral = std::is_integral< TYPE >::value, \
    }; \
}

#define Q_DECLARE_TYPEINFO(TYPE, FLAGS) \
template<> \
Q_DECLARE_TYPEINFO_BODY(TYPE, FLAGS)

(3)Qt 里重要地方基础类 QFlags ,其支持了对枚举量的或运算

//统计本标志类支持的运算符: &= |= ^= !=  ==复合, & | ^ ~ 单目,禁止 + -
template<typename Enum> //模板参数 Enum 是枚举类型
class QFlags
{
    //此静态断言是要求本模板类中的模板参数的类型的大小不可以超过 int
    static_assert((sizeof(Enum) <= sizeof(int)),
        "QFlags uses an int as storage, so an enum with underlying "
        "long long will overflow.");

/* // is_enum
    template<typename _Tp> 可见所谓枚举类型就是要求必须是整数类型
    struct is_enum : public integral_constant<bool, __is_enum(_Tp)> { };
*/
    static_assert((std::is_enum<Enum>::value),
        "QFlags is only usable on enumeration types.");

private:
    constexpr static inline
    Int initializer_list_helper( //静态的私有成员函数
        typename std::initializer_list<Enum>::const_iterator it,
        typename std::initializer_list<Enum>::const_iterator end) noexcept
    {
        return (it == end ?
                   Int(0) :
                   (  Int(*it) | initializer_list_helper(it + 1, end)  )
                  );
    }

    Int i; //此 Int 的定义在下面。定义了本类的数据成员,存储了一个整形数值

public:
#if defined(Q_CC_MSVC) || defined(Q_CLANG_QDOC)
    // see above for MSVC
    // the definition below is too complex for qdoc
    typedef int Int;
#else // 此 else 是有效的
    typedef typename std::conditional< //又是 conditional
        std::is_unsigned<typename std::underlying_type<Enum>::type>::value,
        unsigned int,
        signed int
        >::type Int;
#endif

    typedef Enum enum_type; //对模板参数做了重命名

    // compiler-generated copy/move ctor/assignment operators are fine!
    constexpr inline QFlags() noexcept : i(0) {} //默认构造函数

    constexpr inline Q_IMPLICIT QFlags(Enum flags) noexcept
        : i(Int(flags)) {} //有参构造函数

    constexpr inline Q_IMPLICIT QFlags(QFlag flag) noexcept :
        i(flag) {}             //class QFlag { int i; }

    constexpr inline QFlags(std::initializer_list<Enum> flags) noexcept
        : i(initializer_list_helper(flags.begin(), flags.end())) {}

    //本静态成员函数根据形参的整数 i 构造并返回一个本 QFlags 对象
    constexpr static inline QFlags fromInt(Int i) noexcept
    { return QFlags(QFlag(i)); }

    //把本类型的值转化为整数返回
    constexpr inline Int toInt() const noexcept { return i; }

    //类型转换函数
    constexpr inline operator Int() const noexcept { return i; }

    constexpr inline bool operator!() const noexcept { return !i; }

    constexpr inline QFlags & operator&=(int mask) noexcept
    { i &= mask     ; return *this; } //运算符函数 &= 与等于

    constexpr inline QFlags & operator&=(uint mask) noexcept
    { i &= mask     ; return *this; } //运算符函数 &= 重载

    constexpr inline QFlags & operator&=(QFlags mask) noexcept
    { i &= mask.i   ; return *this; } //运算符函数 &= 重载

    constexpr inline QFlags & operator&=(Enum mask) noexcept
    { i &= Int(mask); return *this; } //运算符函数 &= 重载

    constexpr inline QFlags & operator|=(QFlags other) noexcept
    { i |= other.i   ; return *this; }  //运算符函数 |= 或等于

    constexpr inline QFlags &operator|=(Enum other) noexcept
    { i |= Int(other); return *this; }  //运算符函数 |= 重载

    constexpr inline QFlags &operator^=(QFlags other) noexcept
    { i ^= other.i   ; return *this; }  //运算符函数 ^= 异或等于

    constexpr inline QFlags &operator^=(Enum other) noexcept
    { i ^= Int(other); return *this; }  //运算符函数 ^= 重载

    friend constexpr inline bool operator==(QFlags lhs, QFlags rhs) noexcept
    { return lhs.i == rhs.i; }

    friend constexpr inline bool operator==(QFlags lhs, Enum rhs) noexcept
    { return lhs == QFlags(rhs); }

    friend constexpr inline bool operator==(Enum lhs, QFlags rhs) noexcept
    { return QFlags(lhs) == rhs; }

    friend constexpr inline bool operator!=(QFlags lhs, QFlags rhs) noexcept
    { return lhs.i != rhs.i; }

    friend constexpr inline bool operator!=(QFlags lhs, Enum rhs) noexcept
    { return lhs != QFlags(rhs); }

    friend constexpr inline bool operator!=(Enum lhs, QFlags rhs) noexcept
    { return QFlags(lhs) != rhs; }

    constexpr inline QFlags operator|(QFlags other) const noexcept
    { return QFlags(QFlag(i | other.i)); }  //定义了运算符 | 按位或

    constexpr inline QFlags operator|(Enum other) const noexcept
    { return QFlags(QFlag(i | Int(other))); }

    constexpr inline QFlags operator^(QFlags other) const noexcept
    { return QFlags(QFlag(i ^ other.i)); }  //定义了运算符 ^ 异或

    constexpr inline QFlags operator^(Enum other) const noexcept
    { return QFlags(QFlag(i ^ Int(other))); }

    constexpr inline QFlags operator&(int mask) const noexcept
    { return QFlags(QFlag(i & mask)); }    //定义了运算符 & 与

    constexpr inline QFlags operator&(uint mask) const noexcept
    { return QFlags(QFlag(i & mask)); }

    constexpr inline QFlags operator&(QFlags other) const noexcept
    { return QFlags(QFlag(i & other.i)); }

    constexpr inline QFlags operator&(Enum other) const noexcept
    { return QFlags(QFlag(i & Int(other))); }

    constexpr inline QFlags operator~() const noexcept
    { return QFlags(QFlag(~i)); }         //定义了运算符 ~ 取反

    constexpr inline void operator+(QFlags other) const noexcept = delete;
    constexpr inline void operator+(Enum   other) const noexcept = delete;
    constexpr inline void operator+(int    other) const noexcept = delete;
    constexpr inline void operator-(QFlags other) const noexcept = delete;
    constexpr inline void operator-(Enum   other) const noexcept = delete;
    constexpr inline void operator-(int    other) const noexcept = delete;

    constexpr inline bool testFlags(QFlags flags) const noexcept
    { return    flags.i
                ? ((i & flags.i) == flags.i)
                : i == Int(0);
    }

    constexpr inline bool testFlag(Enum flag) const noexcept
    { return testFlags(flag); }

    constexpr inline bool testAnyFlags(QFlags flags) const noexcept
    { return (i & flags.i) != Int(0); }

    constexpr inline bool testAnyFlag (Enum flag) const noexcept
    { return testAnyFlags(flag); }

    constexpr inline QFlags & setFlag(Enum flag, bool on = true) noexcept
    {   //形参 true则添加标志 , false 则去掉标志
        return on ? (*this |= flag) : (*this &= ~QFlags(flag));
    }
}; //class QFlags

(4)两个重要的宏的定义 Q_DECLARE_FLAGS(Flags, Enum),以及 Q_DECLARE_OPERATORS_FOR_FLAGS(Flags)

#ifndef Q_MOC_RUN
#define Q_DECLARE_FLAGS(Flags, Enum)\
typedef QFlags<Enum> Flags;
#endif

#define Q_DECLARE_OPERATORS_FOR_FLAGS(Flags) \
constexpr inline QFlags<Flags::enum_type> operator| \
(Flags::enum_type f1, Flags::enum_type f2) noexcept \
{ return QFlags<Flags::enum_type>(f1) | f2; } \
\
constexpr inline QFlags<Flags::enum_type> operator| \
(Flags::enum_type f1, QFlags<Flags::enum_type> f2) noexcept \
{ return f2 | f1; } \
\
constexpr inline QFlags<Flags::enum_type> operator& \
(Flags::enum_type f1, Flags::enum_type f2) noexcept \
{ return QFlags<Flags::enum_type>(f1) & f2; } \
\
constexpr inline QFlags<Flags::enum_type> operator& \
(Flags::enum_type f1, QFlags<Flags::enum_type> f2) noexcept \
{ return f2 & f1; } \
\
constexpr inline \
void operator+(Flags::enum_type f1,Flags::enum_type f2) noexcept = delete; \
\
constexpr inline \
void operator+(Flags::enum_type f1, QFlags<Flags::enum_type> f2) noexcept = delete; \
\
constexpr inline \
void operator+(int f1, QFlags<Flags::enum_type> f2) noexcept = delete; \
\
constexpr inline \
void operator-(Flags::enum_type f1, Flags::enum_type f2) noexcept = delete; \
\
constexpr inline \
void operator-(Flags::enum_type f1, QFlags<Flags::enum_type> f2) noexcept = delete; \
\
constexpr inline \
void operator-(int f1, QFlags<Flags::enum_type> f2) noexcept = delete; \
\
constexpr inline \
QIncompatibleFlag operator|(Flags::enum_type f1, int f2) noexcept \
{ return QIncompatibleFlag(int(f1) | f2); } \
\
constexpr inline void operator+(int f1, Flags::enum_type f2) noexcept = delete; \
constexpr inline void operator+(Flags::enum_type f1, int f2) noexcept = delete; \
constexpr inline void operator-(int f1, Flags::enum_type f2) noexcept = delete; \
constexpr inline void operator-(Flags::enum_type f1, int f2) noexcept = delete;

(5)

谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值