Skip to content

Commit

Permalink
Implement P0298R3: 'std::byte'. Reviewed as https://reviews.llvm.org/…
Browse files Browse the repository at this point in the history
…D31022

llvm-svn: 298689
  • Loading branch information
mclow committed Mar 24, 2017
1 parent 059b98e commit c97d8aa
Show file tree
Hide file tree
Showing 21 changed files with 623 additions and 1 deletion.
29 changes: 29 additions & 0 deletions libcxx/include/cstddef
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Types:
size_t
max_align_t
nullptr_t
byte // C++17
} // std
Expand Down Expand Up @@ -58,4 +59,32 @@ typedef long double max_align_t;

_LIBCPP_END_NAMESPACE_STD

#if _LIBCPP_STD_VER > 14
namespace std // purposefully not versioned
{
enum class byte : unsigned char {};

constexpr byte& operator|=(byte& __lhs, byte __rhs) noexcept
{ return __lhs = byte(static_cast<unsigned char>(__lhs) | static_cast<unsigned char>(__rhs)); }
constexpr byte operator| (byte __lhs, byte __rhs) noexcept
{ return byte(static_cast<unsigned char>(__lhs) | static_cast<unsigned char>(__rhs)); }

constexpr byte& operator&=(byte& __lhs, byte __rhs) noexcept
{ return __lhs = byte(static_cast<unsigned char>(__lhs) & static_cast<unsigned char>(__rhs)); }
constexpr byte operator& (byte __lhs, byte __rhs) noexcept
{ return byte(static_cast<unsigned char>(__lhs) & static_cast<unsigned char>(__rhs)); }

constexpr byte& operator^=(byte& __lhs, byte __rhs) noexcept
{ return __lhs = byte(static_cast<unsigned char>(__lhs) ^ static_cast<unsigned char>(__rhs)); }
constexpr byte operator^ (byte __lhs, byte __rhs) noexcept
{ return byte(static_cast<unsigned char>(__lhs) ^ static_cast<unsigned char>(__rhs)); }

constexpr byte operator~ (byte __b) noexcept
{ return byte(~static_cast<unsigned char>(__b)); }

}

#include <type_traits> // rest of byte
#endif

#endif // _LIBCPP_CSTDDEF
31 changes: 31 additions & 0 deletions libcxx/include/type_traits
Original file line number Diff line number Diff line change
Expand Up @@ -4714,4 +4714,35 @@ struct __can_extract_map_key<_ValTy, _Key, _Key, _RawValTy>

_LIBCPP_END_NAMESPACE_STD

#if _LIBCPP_STD_VER > 14
// std::byte
namespace std // purposefully not versioned
{
template <class _Integer>
constexpr typename enable_if<is_integral_v<_Integer>, byte>::type &
operator<<=(byte& __lhs, _Integer __shift) noexcept
{ return __lhs = byte(static_cast<unsigned char>(__lhs) << __shift); }

template <class _Integer>
constexpr typename enable_if<is_integral_v<_Integer>, byte>::type
operator<< (byte __lhs, _Integer __shift) noexcept
{ return byte(static_cast<unsigned char>(__lhs) << __shift); }

template <class _Integer>
constexpr typename enable_if<is_integral_v<_Integer>, byte>::type &
operator>>=(byte& __lhs, _Integer __shift) noexcept
{ return __lhs = byte(static_cast<unsigned char>(__lhs) >> __shift); }

template <class _Integer>
constexpr typename enable_if<is_integral_v<_Integer>, byte>::type
operator>> (byte __lhs, _Integer __shift) noexcept
{ return byte(static_cast<unsigned char>(__lhs) >> __shift); }

template <class _Integer>
constexpr typename enable_if<is_integral_v<_Integer>, _Integer>::type
to_integer(byte __b) noexcept { return _Integer(__b); }

}
#endif

#endif // _LIBCPP_TYPE_TRAITS
30 changes: 30 additions & 0 deletions libcxx/test/std/language.support/support.types/byte.pass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//===----------------------------------------------------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//

#include <cstddef>
#include <type_traits>
#include <test_macros.h>

// XFAIL: c++98, c++03, c++11, c++14

// std::byte is not an integer type, nor a character type.
// It is a distinct type for accessing the bits that ultimately make up object storage.

static_assert( std::is_pod<std::byte>::value, "" );
static_assert(!std::is_arithmetic<std::byte>::value, "" );
static_assert(!std::is_integral<std::byte>::value, "" );

static_assert(!std::is_same<std::byte, char>::value, "" );
static_assert(!std::is_same<std::byte, signed char>::value, "" );
static_assert(!std::is_same<std::byte, unsigned char>::value, "" );

// The standard doesn't outright say this, but it's pretty clear that it has to be true.
static_assert(sizeof(std::byte) == 1, "" );

int main () {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//===----------------------------------------------------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//

#include <cstddef>
#include <test_macros.h>

// UNSUPPORTED: c++98, c++03, c++11, c++14

// constexpr byte& operator &=(byte l, byte r) noexcept;


constexpr std::byte test(std::byte b1, std::byte b2) {
std::byte bret = b1;
return bret &= b2;
}


int main () {
std::byte b; // not constexpr, just used in noexcept check
constexpr std::byte b1{1};
constexpr std::byte b8{8};
constexpr std::byte b9{9};

static_assert(noexcept(b &= b), "" );

static_assert(std::to_integer<int>(test(b1, b8)) == 0, "");
static_assert(std::to_integer<int>(test(b1, b9)) == 1, "");
static_assert(std::to_integer<int>(test(b8, b9)) == 8, "");

static_assert(std::to_integer<int>(test(b8, b1)) == 0, "");
static_assert(std::to_integer<int>(test(b9, b1)) == 1, "");
static_assert(std::to_integer<int>(test(b9, b8)) == 8, "");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//===----------------------------------------------------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//

#include <cstddef>
#include <test_macros.h>

// UNSUPPORTED: c++98, c++03, c++11, c++14

// constexpr byte operator&(byte l, byte r) noexcept;

int main () {
constexpr std::byte b1{1};
constexpr std::byte b8{8};
constexpr std::byte b9{9};

static_assert(noexcept(b1 & b8), "" );

static_assert(std::to_integer<int>(b1 & b8) == 0, "");
static_assert(std::to_integer<int>(b1 & b9) == 1, "");
static_assert(std::to_integer<int>(b8 & b9) == 8, "");

static_assert(std::to_integer<int>(b8 & b1) == 0, "");
static_assert(std::to_integer<int>(b9 & b1) == 1, "");
static_assert(std::to_integer<int>(b9 & b8) == 8, "");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//===----------------------------------------------------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//

#include <cstddef>
#include <test_macros.h>

// UNSUPPORTED: c++98, c++03, c++11, c++14

// template <class IntegerType>
// constexpr byte& operator<<=(byte& b, IntegerType shift) noexcept;
// This function shall not participate in overload resolution unless
// is_integral_v<IntegerType> is true.


constexpr std::byte test(std::byte b) {
return b <<= 2.0;
}


int main () {
constexpr std::byte b1 = test(std::byte{1});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//===----------------------------------------------------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//

#include <cstddef>
#include <test_macros.h>

// UNSUPPORTED: c++98, c++03, c++11, c++14

// template <class IntegerType>
// constexpr byte& operator<<=(byte& b, IntegerType shift) noexcept;
// This function shall not participate in overload resolution unless
// is_integral_v<IntegerType> is true.


constexpr std::byte test(std::byte b) {
return b <<= 2;
}


int main () {
std::byte b; // not constexpr, just used in noexcept check
constexpr std::byte b2{2};
constexpr std::byte b3{3};

static_assert(noexcept(b <<= 2), "" );

static_assert(std::to_integer<int>(test(b2)) == 8, "" );
static_assert(std::to_integer<int>(test(b3)) == 12, "" );

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//===----------------------------------------------------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//

#include <cstddef>
#include <test_macros.h>

// UNSUPPORTED: c++98, c++03, c++11, c++14

// template <class IntegerType>
// constexpr byte operator <<(byte b, IntegerType shift) noexcept;
// These functions shall not participate in overload resolution unless
// is_integral_v<IntegerType> is true.

int main () {
constexpr std::byte b1{1};
constexpr std::byte b2 = b1 << 2.0f;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//===----------------------------------------------------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//

#include <cstddef>
#include <test_macros.h>

// UNSUPPORTED: c++98, c++03, c++11, c++14

// template <class IntegerType>
// constexpr byte operator <<(byte b, IntegerType shift) noexcept;
// These functions shall not participate in overload resolution unless
// is_integral_v<IntegerType> is true.

int main () {
constexpr std::byte b1{1};
constexpr std::byte b3{3};

static_assert(noexcept(b3 << 2), "" );

static_assert(std::to_integer<int>(b1 << 1) == 2, "");
static_assert(std::to_integer<int>(b1 << 2) == 4, "");
static_assert(std::to_integer<int>(b3 << 4) == 48, "");
static_assert(std::to_integer<int>(b3 << 6) == 192, "");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//===----------------------------------------------------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//

#include <cstddef>
#include <test_macros.h>

// UNSUPPORTED: c++98, c++03, c++11, c++14

// constexpr byte operator~(byte b) noexcept;

int main () {
constexpr std::byte b1{1};
constexpr std::byte b2{2};
constexpr std::byte b8{8};

static_assert(noexcept(~b1), "" );

static_assert(std::to_integer<int>(~b1) == 254, "");
static_assert(std::to_integer<int>(~b2) == 253, "");
static_assert(std::to_integer<int>(~b8) == 247, "");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//===----------------------------------------------------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//

#include <cstddef>
#include <test_macros.h>

// UNSUPPORTED: c++98, c++03, c++11, c++14

// constexpr byte& operator |=(byte l, byte r) noexcept;


constexpr std::byte test(std::byte b1, std::byte b2) {
std::byte bret = b1;
return bret |= b2;
}


int main () {
std::byte b; // not constexpr, just used in noexcept check
constexpr std::byte b1{1};
constexpr std::byte b2{2};
constexpr std::byte b8{8};

static_assert(noexcept(b |= b), "" );

static_assert(std::to_integer<int>(test(b1, b2)) == 3, "");
static_assert(std::to_integer<int>(test(b1, b8)) == 9, "");
static_assert(std::to_integer<int>(test(b2, b8)) == 10, "");

static_assert(std::to_integer<int>(test(b2, b1)) == 3, "");
static_assert(std::to_integer<int>(test(b8, b1)) == 9, "");
static_assert(std::to_integer<int>(test(b8, b2)) == 10, "");

}
Loading

0 comments on commit c97d8aa

Please sign in to comment.