[PATCH] D35472: Implement P0463R1: "Endian just Endian"

Roman Lebedev via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 17 02:40:56 PDT 2017


On Mon, Jul 17, 2017 at 6:08 AM, Marshall Clow via Phabricator via
cfe-commits <cfe-commits at lists.llvm.org> wrote:
> mclow.lists created this revision.
>
> Implement the C++2a feature "A compile time endian-ness detection idiom"
> Howard's suggested implementation is:
>
> enum class endian
>         {
>         #ifdef _WIN32
>
>                 little = 0,
>                 big    = 1,
>                 native = little
>
> #else
>
>                 little = __ORDER_LITTLE_ENDIAN__,
>                 big    = __ORDER_BIG_ENDIAN__
>                 native = __BYTE_ORDER__,
>
> #endif
>         };
>
> but libc++ has it's own macros that have done the work to detect this.
>
> The other option would be to rip out `_LIBCPP_LITTLE_ENDIAN` and `_LIBCPP_BIG_ENDIAN`, which is tempting, but that would entail changes in code that has to compile for earlier C++ language versions.
>
>
> https://reviews.llvm.org/D35472
>
> Files:
>   include/type_traits
>   test/std/utilities/meta/meta.type.synop/endian.pass.cpp
>
>
> Index: test/std/utilities/meta/meta.type.synop/endian.pass.cpp
> ===================================================================
> --- test/std/utilities/meta/meta.type.synop/endian.pass.cpp
> +++ test/std/utilities/meta/meta.type.synop/endian.pass.cpp
> @@ -0,0 +1,46 @@
> +//===----------------------------------------------------------------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++14, c++17
> +
> +// enum class endian;
> +
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +int main() {
> +    typedef std::endian E;
> +    static_assert(std::is_enum<std::endian>::value, "");
> +
> +// Check that E is a scoped enum by checking for conversions.
> +    typedef std::underlying_type<std::endian>::type UT;
> +    static_assert(!std::is_convertible<std::endian, UT>::value, "");
> +
> +// test that the enumeration values exist
> +    static_assert( std::endian::little == std::endian::little );
> +    static_assert( std::endian::big    == std::endian::big );
> +    static_assert( std::endian::native == std::endian::native );
> +    static_assert( std::endian::little != std::endian::big );
> +
> +//  Technically not required, but true on all existing machines
> +    static_assert( std::endian::native == std::endian::little ||
> +                   std::endian::native == std::endian::big );
> +
> +//  Try to check at runtime
> +    {
> +    union {
> +        uint32_t i;
> +        char c[4];
> +    } u = {0x01020304};
> +
> +    assert ((u.c[0] == 1) == (std::endian::native == std::endian::big));
> +    }
> +}
> Index: include/type_traits
> ===================================================================
> --- include/type_traits
> +++ include/type_traits
> @@ -4737,6 +4737,21 @@
>
>  #endif

I'm probably wrong, but if this is a C++2a proposal, shouldn't this
> +#if _LIBCPP_STD_VER > 14
be
#if _LIBCPP_STD_VER > 17
?

> +enum class endian
> +{
> +    little = 0xDEAD,
> +    big    = 0xFACE,
> +#if _LIBCPP_LITTLE_ENDIAN
> +    native = little
> +#elif _LIBCPP_BIG_ENDIAN
> +    native = big
> +#else
> +    native = 0xCAFE
> +#endif
> +};
> +#endif
> +
>  _LIBCPP_END_NAMESPACE_STD
>
>  #if _LIBCPP_STD_VER > 14

Roman.
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>


More information about the cfe-commits mailing list