On Mon, Jul 17, 2017 at 6:08 AM, Marshall Clow via Phabricator via cfe-commits <cfe-commits@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@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits