diff --git a/libc/src/__support/CPP/CMakeLists.txt b/libc/src/__support/CPP/CMakeLists.txt --- a/libc/src/__support/CPP/CMakeLists.txt +++ b/libc/src/__support/CPP/CMakeLists.txt @@ -16,6 +16,12 @@ bitset.h ) +add_header_library( + byte + HDRS + byte.h +) + add_header_library( functional HDRS diff --git a/libc/src/__support/CPP/byte.h b/libc/src/__support/CPP/byte.h new file mode 100644 --- /dev/null +++ b/libc/src/__support/CPP/byte.h @@ -0,0 +1,58 @@ +//===-- A self contained equivalent of byte ----------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_BYTE_H +#define LLVM_LIBC_SRC_SUPPORT_CPP_BYTE_H + +#include // For size_t. +namespace __llvm_libc::cpp { + +enum class byte : unsigned char {}; + +template +static inline constexpr byte operator<<(byte b, IntegerType shift) { + return byte(static_cast(b) << shift); +} +template +static inline constexpr byte operator>>(byte b, IntegerType shift) { + return byte(static_cast(b) >> shift); +} +static inline constexpr byte operator|(byte l, byte r) { + return byte(static_cast(l) | static_cast(r)); +} +static inline constexpr byte operator&(byte l, byte r) { + return byte(static_cast(l) & static_cast(r)); +} +static inline constexpr byte operator^(byte l, byte r) { + return byte(static_cast(l) ^ static_cast(r)); +} +static inline constexpr byte operator~(byte b) { + return byte(~static_cast(b)); +} +static inline constexpr byte &operator|=(byte &l, byte r) { return l = l | r; } +static inline constexpr byte &operator&=(byte &l, byte r) { return l = l & r; } +static inline constexpr byte &operator^=(byte &l, byte r) { return l = l ^ r; } +template +static inline constexpr byte &operator<<=(byte &b, IntegerType shift) { + return b = b << shift; +} +template +static inline constexpr byte &operator>>=(byte &b, IntegerType shift) { + return b = b >> shift; +} + +} // namespace __llvm_libc::cpp + +namespace __llvm_libc { +template +static inline constexpr IntegerType to_integer(cpp::byte b) { + return IntegerType(b); +} +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_SUPPORT_CPP_BYTE_H diff --git a/libc/test/src/__support/CPP/CMakeLists.txt b/libc/test/src/__support/CPP/CMakeLists.txt --- a/libc/test/src/__support/CPP/CMakeLists.txt +++ b/libc/test/src/__support/CPP/CMakeLists.txt @@ -10,6 +10,16 @@ libc.src.__support.CPP.bitset ) +add_libc_unittest( + byte_test + SUITE + libc_cpp_utils_unittests + SRCS + byte_test.cpp + DEPENDS + libc.src.__support.CPP.byte +) + add_libc_unittest( stringview_test SUITE diff --git a/libc/test/src/__support/CPP/byte_test.cpp b/libc/test/src/__support/CPP/byte_test.cpp new file mode 100644 --- /dev/null +++ b/libc/test/src/__support/CPP/byte_test.cpp @@ -0,0 +1,44 @@ +//===-- Unittests for byte ------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/__support/CPP/byte.h" +#include "utils/UnitTest/Test.h" + +namespace __llvm_libc { + +TEST(LlvmLibcByteTest, to_integer) { + const char str[] = "abc"; + const cpp::byte *const ptr = reinterpret_cast(str); + ASSERT_EQ(to_integer(ptr[0]), 'a'); + ASSERT_EQ(to_integer(ptr[1]), 'b'); + ASSERT_EQ(to_integer(ptr[2]), 'c'); + ASSERT_EQ(to_integer(ptr[3]), '\0'); +} + +TEST(LlvmLibcByteTest, bitwise) { + cpp::byte b{42}; + ASSERT_EQ(b, cpp::byte{0b00101010}); + + b <<= 1; + ASSERT_EQ(b, cpp::byte{0b01010100}); + b >>= 1; + + ASSERT_EQ((b << 1), cpp::byte{0b01010100}); + ASSERT_EQ((b >> 1), cpp::byte{0b00010101}); + + b |= cpp::byte{0b11110000}; + ASSERT_EQ(b, cpp::byte{0b11111010}); + + b &= cpp::byte{0b11110000}; + ASSERT_EQ(b, cpp::byte{0b11110000}); + + b ^= cpp::byte{0b11111111}; + ASSERT_EQ(b, cpp::byte{0b00001111}); +} + +} // namespace __llvm_libc