diff --git a/libc/src/__support/CPP/ArrayRef.h b/libc/src/__support/CPP/ArrayRef.h --- a/libc/src/__support/CPP/ArrayRef.h +++ b/libc/src/__support/CPP/ArrayRef.h @@ -58,7 +58,7 @@ bool empty() const { return size() == 0; } - auto operator[](size_t Index) const { return data()[Index]; } + auto &operator[](size_t Index) const { return data()[Index]; } // slice(n, m) - Chop off the first N elements of the array, and keep M // elements in the array. @@ -115,6 +115,11 @@ using Impl::Impl; public: + // Construct an ArrayRef from void * pointer. + // |Length| is the byte length of the array pointed to by |Data|. + ArrayRef(const void *Data, size_t Length) + : Impl(reinterpret_cast(Data), Length / sizeof(T)) {} + // From Array. template ArrayRef(const Array &Arr) : Impl(Arr.Data, N) {} }; @@ -129,6 +134,11 @@ using Impl::Impl; public: + // Construct an ArrayRef from void * pointer. + // |Length| is the byte length of the array pointed to by |Data|. + MutableArrayRef(void *Data, size_t Length) + : Impl(reinterpret_cast(Data), Length / sizeof(T)) {} + // From Array. template MutableArrayRef(Array &Arr) : Impl(Arr.Data, N) {} diff --git a/libc/test/src/__support/CPP/arrayref_test.cpp b/libc/test/src/__support/CPP/arrayref_test.cpp --- a/libc/test/src/__support/CPP/arrayref_test.cpp +++ b/libc/test/src/__support/CPP/arrayref_test.cpp @@ -218,5 +218,22 @@ } } +TEST(LlvmLibcArrayRefTest, ConstructFromVoidPtr) { + unsigned data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + void *ptr = data; + const void *const_ptr = data; + ArrayRef ref(const_ptr, sizeof(data)); + MutableArrayRef mutable_ref(ptr, sizeof(data)); + ASSERT_EQ(ref.size(), sizeof(data) / sizeof(unsigned)); + ASSERT_EQ(mutable_ref.size(), sizeof(data) / sizeof(unsigned)); + + unsigned val = 123; + for (size_t i = 0; i < sizeof(data) / sizeof(unsigned); ++i) + mutable_ref[i] = val; + + for (size_t i = 0; i < sizeof(data) / sizeof(unsigned); ++i) + ASSERT_EQ(ref[i], val); +} + } // namespace cpp } // namespace __llvm_libc