[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