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,14 @@ bitset.h ) +add_header_library( + cstddef + HDRS + cstddef.h + DEPENDS + .type_traits +) + add_header_library( functional HDRS diff --git a/libc/src/__support/CPP/cstddef.h b/libc/src/__support/CPP/cstddef.h new file mode 100644 --- /dev/null +++ b/libc/src/__support/CPP/cstddef.h @@ -0,0 +1,64 @@ +//===-- A self contained equivalent of cstddef ------------------*- 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 "type_traits.h" // For enable_if_t, is_integral_v. + +namespace __llvm_libc::cpp { + +enum class byte : unsigned char {}; + +template +constexpr enable_if_t, byte> +operator>>(byte b, IntegerType shift) noexcept { + return static_cast(static_cast(b) >> shift); +} +template +constexpr enable_if_t, byte &> +operator>>=(byte &b, IntegerType shift) noexcept { + return b = b >> shift; +} +template +constexpr enable_if_t, byte> +operator<<(byte b, IntegerType shift) noexcept { + return static_cast(static_cast(b) << shift); +} +template +constexpr enable_if_t, byte &> +operator<<=(byte &b, IntegerType shift) noexcept { + return b = b << shift; +} +constexpr byte operator|(byte l, byte r) noexcept { + return static_cast(static_cast(l) | + static_cast(r)); +} +constexpr byte &operator|=(byte &l, byte r) noexcept { return l = l | r; } +constexpr byte operator&(byte l, byte r) noexcept { + return static_cast(static_cast(l) & + static_cast(r)); +} +constexpr byte &operator&=(byte &l, byte r) noexcept { return l = l & r; } +constexpr byte operator^(byte l, byte r) noexcept { + return static_cast(static_cast(l) ^ + static_cast(r)); +} +constexpr byte &operator^=(byte &l, byte r) noexcept { return l = l ^ r; } +constexpr byte operator~(byte b) noexcept { + return static_cast(~static_cast(b)); +} +template +constexpr enable_if_t, IntegerType> +to_integer(byte b) noexcept { + return static_cast(b); +} + +} // namespace __llvm_libc::cpp + +#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( + cstddef_test + SUITE + libc_cpp_utils_unittests + SRCS + cstddef_test.cpp + DEPENDS + libc.src.__support.CPP.cstddef +) + add_libc_unittest( stringview_test SUITE diff --git a/libc/test/src/__support/CPP/cstddef_test.cpp b/libc/test/src/__support/CPP/cstddef_test.cpp new file mode 100644 --- /dev/null +++ b/libc/test/src/__support/CPP/cstddef_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/cstddef.h" +#include "utils/UnitTest/Test.h" + +namespace __llvm_libc::cpp { + +TEST(LlvmLibcByteTest, to_integer) { + const char str[] = "abc"; + const 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) { + byte b{42}; + ASSERT_EQ(b, byte{0b00101010}); + + b <<= 1; + ASSERT_EQ(b, byte{0b01010100}); + b >>= 1; + + ASSERT_EQ((b << 1), byte{0b01010100}); + ASSERT_EQ((b >> 1), byte{0b00010101}); + + b |= byte{0b11110000}; + ASSERT_EQ(b, byte{0b11111010}); + + b &= byte{0b11110000}; + ASSERT_EQ(b, byte{0b11110000}); + + b ^= byte{0b11111111}; + ASSERT_EQ(b, byte{0b00001111}); +} + +} // namespace __llvm_libc::cpp diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -54,6 +54,15 @@ deps = [":libc_root"], ) +cc_library( + name = "__support_cpp_cstddef", + hdrs = ["src/__support/CPP/cstddef.h"], + deps = [ + "__support_cpp_type_traits", + ":libc_root", + ], +) + cc_library( name = "__support_cpp_functional", hdrs = ["src/__support/CPP/functional.h"],