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 +#if _LIBCPP_STD_VER > 14 +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
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 +#if _LIBCPP_STD_VER > 14 +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
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits