-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Support] Add llvm::support::endian::writeNext #88685
[Support] Add llvm::support::endian::writeNext #88685
Conversation
Created using spr 1.3.5-bogner
@llvm/pr-subscribers-llvm-support Author: Fangrui Song (MaskRay) Changes
can be simplified to:
Full diff: https://github.com/llvm/llvm-project/pull/88685.diff 2 Files Affected:
diff --git a/llvm/include/llvm/Support/Endian.h b/llvm/include/llvm/Support/Endian.h
index 4c0405cf1e2f69..1cdb5ca0d5eaa1 100644
--- a/llvm/include/llvm/Support/Endian.h
+++ b/llvm/include/llvm/Support/Endian.h
@@ -102,6 +102,21 @@ inline void write(void *memory, value_type value) {
write<value_type, alignment>(memory, value, endian);
}
+/// Write a value of a particular endianness, and increment the buffer past that
+/// value.
+template <typename value_type, std::size_t alignment = unaligned,
+ typename CharT>
+inline void writeNext(CharT *&memory, value_type value, endianness endian) {
+ write(memory, value, endian);
+ memory += sizeof(value_type);
+}
+
+template <typename value_type, endianness endian,
+ std::size_t alignment = unaligned, typename CharT>
+inline void writeNext(CharT *&memory, value_type value) {
+ writeNext<value_type, alignment, CharT>(memory, value, endian);
+}
+
template <typename value_type>
using make_unsigned_t = std::make_unsigned_t<value_type>;
diff --git a/llvm/unittests/Support/EndianTest.cpp b/llvm/unittests/Support/EndianTest.cpp
index ab7dfc3800691d..bba1a56168f709 100644
--- a/llvm/unittests/Support/EndianTest.cpp
+++ b/llvm/unittests/Support/EndianTest.cpp
@@ -36,6 +36,29 @@ TEST(Endian, Read) {
1)));
}
+TEST(Endian, WriteNext) {
+ unsigned char bigval[] = {0x00, 0x00}, *p = bigval;
+ endian::writeNext<int16_t, llvm::endianness::big>(p, short(0xaabb));
+ EXPECT_EQ(bigval[0], 0xaa);
+ EXPECT_EQ(bigval[1], 0xbb);
+ EXPECT_EQ(p, bigval + 2);
+
+ char littleval[8] = {}, *q = littleval;
+ endian::writeNext<uint32_t, llvm::endianness::little>(q, 0x44556677);
+ EXPECT_EQ(littleval[0], 0x77);
+ EXPECT_EQ(littleval[1], 0x66);
+ EXPECT_EQ(littleval[2], 0x55);
+ EXPECT_EQ(littleval[3], 0x44);
+ EXPECT_EQ(q, littleval + 4);
+
+ endian::writeNext<uint32_t>(q, 0x11223344, llvm::endianness::little);
+ EXPECT_EQ(littleval[4], 0x44);
+ EXPECT_EQ(littleval[5], 0x33);
+ EXPECT_EQ(littleval[6], 0x22);
+ EXPECT_EQ(littleval[7], 0x11);
+ EXPECT_EQ(q, littleval + 8);
+}
+
TEST(Endian, ReadBitAligned) {
// Simple test to make sure we properly pull out the 0x0 word.
unsigned char littleval[] = {0x3f, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff};
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good stuff - thanks!
`writeNext` overloads increase the pointer argument like `readNext`. Code like the following ``` endian::write32<ELFT::Endianness>(p, 42); p += 4; endian::write32<ELFT::Endianness>(p, 43); p += 4; ``` can be simplified to: ``` endian::writeNext<uint32_t, ELFT::Endianness>(p, 42); endian::writeNext<uint32_t, ELFT::Endianness>(p, 43); ```
writeNext
overloads increase the pointer argument likereadNext
.Code like the following
can be simplified to: