constexpr and endianness

后端 未结 8 561
無奈伤痛
無奈伤痛 2020-12-24 12:42

A common question that comes up from time to time in the world of C++ programming is compile-time determination of endianness. Usually this is done with barely portable #if

8条回答
  •  暗喜
    暗喜 (楼主)
    2020-12-24 12:47

    My first post. Just wanted to share some code that I'm using.

    //Some handy defines magic, thanks overflow
    #define IS_LITTLE_ENDIAN  ('ABCD'==0x41424344UL) //41 42 43 44 = 'ABCD' hex ASCII code
    #define IS_BIG_ENDIAN     ('ABCD'==0x44434241UL) //44 43 42 41 = 'DCBA' hex ASCII code
    #define IS_UNKNOWN_ENDIAN (IS_LITTLE_ENDIAN == IS_BIG_ENDIAN)
    
    //Next in code...
    struct Quad
    {
        union
        {
    #if IS_LITTLE_ENDIAN
            struct { std::uint8_t b0, b1, b2, b3; };
    
    #elif IS_BIG_ENDIAN
            struct { std::uint8_t b3, b2, b1, b0; };
    
    #elif IS_UNKNOWN_ENDIAN
    #error "Endianness not implemented!"
    #endif
    
            std::uint32_t dword;
        };
    };
    

    Constexpr version:

    namespace Endian
    {
        namespace Impl //Private
        {
            //41 42 43 44 = 'ABCD' hex ASCII code
            static constexpr std::uint32_t LITTLE_{ 0x41424344u };
    
            //44 43 42 41 = 'DCBA' hex ASCII code
            static constexpr std::uint32_t BIG_{ 0x44434241u };
    
            //Converts chars to uint32 on current platform
            static constexpr std::uint32_t NATIVE_{ 'ABCD' };
        }
    
    
    
        //Public
        enum class Type : size_t { UNKNOWN, LITTLE, BIG };
    
        //Compare
        static constexpr bool IS_LITTLE   = Impl::NATIVE_ == Impl::LITTLE_;
        static constexpr bool IS_BIG      = Impl::NATIVE_ == Impl::BIG_;
        static constexpr bool IS_UNKNOWN  = IS_LITTLE == IS_BIG;
    
        //Endian type on current platform
        static constexpr Type NATIVE_TYPE = IS_LITTLE ? Type::LITTLE : IS_BIG ? Type::BIG : Type::UNKNOWN;
    
    
    
        //Uncomment for test. 
        //static_assert(!IS_LITTLE, "This platform has little endian.");
        //static_assert(!IS_BIG_ENDIAN, "This platform has big endian.");
        //static_assert(!IS_UNKNOWN, "Error: Unsupported endian!");
    }
    

提交回复
热议问题