<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Jan 28, 2014 at 11:21 AM, Nick Kledzik <span dir="ltr"><<a href="mailto:kledzik@apple.com" target="_blank">kledzik@apple.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: kledzik<br>
Date: Tue Jan 28 13:21:27 2014<br>
New Revision: 200331<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=200331&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=200331&view=rev</a><br>
Log:<br>
Add BumpPtrAllocator::allocateCopy() utilities<br>
<br>
Makes it easy to use BumpPtrAllocator to make a copy of StringRef strings.<br>
<br>
Modified:<br>
    llvm/trunk/include/llvm/Support/Allocator.h<br>
    llvm/trunk/unittests/Support/AllocatorTest.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/Support/Allocator.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Allocator.h?rev=200331&r1=200330&r2=200331&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Allocator.h?rev=200331&r1=200330&r2=200331&view=diff</a><br>


==============================================================================<br>
--- llvm/trunk/include/llvm/Support/Allocator.h (original)<br>
+++ llvm/trunk/include/llvm/Support/Allocator.h Tue Jan 28 13:21:27 2014<br>
@@ -14,6 +14,8 @@<br>
 #ifndef LLVM_SUPPORT_ALLOCATOR_H<br>
 #define LLVM_SUPPORT_ALLOCATOR_H<br>
<br>
+#include "llvm/ADT/ArrayRef.h"<br>
+#include "llvm/ADT/StringRef.h"<br>
 #include "llvm/Support/AlignOf.h"<br>
 #include "llvm/Support/DataTypes.h"<br>
 #include "llvm/Support/MathExtras.h"<br>
@@ -179,6 +181,40 @@ public:<br></blockquote><div><br></div><div>Hi Nick,</div><div><br></div><div>It strikes me as strange to add a dependency for Allocator on StringRef for this case (and I guess on ArrayRef too). If this is a service StringRef needs from Allocator and not vice versa, wouldn't it make more sense to add this utility method to StringRef (taking an Allocator)?</div>

<div><br></div><div>Eli</div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
   void PrintStats() const;<br>
<br>
+<br>
+  /// Allocate space and copy content into it.<br>
+  void *allocateCopy(const void *Src, size_t Size, size_t Alignment=1) {<br>
+    void *P = Allocate(Size, Alignment);<br>
+    memcpy(P, Src, Size);<br>
+    return P;<br>
+  }<br>
+<br>
+  /// Allocate space for an array of type T, and use std::copy()<br>
+  /// to copy the array contents.<br>
+  template <typename T><br>
+  typename enable_if<isPodLike<T>, T*>::type<br>
+  allocateCopy(const T Src[], size_t Num) {<br>
+    T *P = Allocate<T>(Num);<br>
+    std::copy(Src, &Src[Num], P);<br>
+    return P;<br>
+  }<br>
+<br>
+  /// Copy a StringRef by allocating copy in BumpPtrAllocator.<br>
+  StringRef allocateCopy(StringRef Str) {<br>
+    size_t Length = Str.size();<br>
+    char *P = allocateCopy<char>(Str.data(), Length);<br>
+    return StringRef(P, Length);<br>
+  }<br>
+<br>
+  /// Copy a ArrayRef<T> by allocating copy in BumpPtrAllocator.<br>
+  template <typename T><br>
+  typename enable_if<isPodLike<T>, ArrayRef<T>>::type<br>
+  allocateCopy(ArrayRef<T> Src) {<br>
+    size_t Length = Src.size();<br>
+    T *P = allocateCopy(Src.data(), Length*sizeof(T));<br>
+    return makeArrayRef(P, Length);<br>
+  }<br>
+<br>
   /// Compute the total physical memory allocated by this allocator.<br>
   size_t getTotalMemory() const;<br>
 };<br>
<br>
Modified: llvm/trunk/unittests/Support/AllocatorTest.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/AllocatorTest.cpp?rev=200331&r1=200330&r2=200331&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/AllocatorTest.cpp?rev=200331&r1=200330&r2=200331&view=diff</a><br>


==============================================================================<br>
--- llvm/trunk/unittests/Support/AllocatorTest.cpp (original)<br>
+++ llvm/trunk/unittests/Support/AllocatorTest.cpp Tue Jan 28 13:21:27 2014<br>
@@ -147,4 +147,32 @@ TEST(AllocatorTest, TestBigAlignment) {<br>
   EXPECT_LE(Ptr + 3000, ((uintptr_t)Slab) + Slab->Size);<br>
 }<br>
<br>
+TEST(AllocatorTest, CopyStringRef) {<br>
+  BumpPtrAllocator Alloc;<br>
+  StringRef Str1 = "hello";<br>
+  StringRef Str2 = "bye";<br>
+  StringRef Str1c = Alloc.allocateCopy(Str1);<br>
+  StringRef Str2c = Alloc.allocateCopy(Str2);<br>
+  EXPECT_TRUE(Str1.equals(Str1c));<br>
+  EXPECT_NE(Str1.data(), Str1c.data());<br>
+  EXPECT_TRUE(Str2.equals(Str2c));<br>
+  EXPECT_NE(Str2.data(), Str2c.data());<br>
+}<br>
+<br>
+TEST(AllocatorTest, CopyArrayRef) {<br>
+  BumpPtrAllocator Alloc;<br>
+  static const uint16_t Words1[] = { 1, 4, 200, 37 };<br>
+  ArrayRef<uint16_t> Array1 = makeArrayRef(Words1, 4);<br>
+  static const uint16_t Words2[] = { 11, 4003, 67, 64000, 13 };<br>
+  ArrayRef<uint16_t> Array2 = makeArrayRef(Words2, 5);<br>
+  ArrayRef<uint16_t> Array1c = Alloc.allocateCopy(Array1);<br>
+  ArrayRef<uint16_t> Array2c = Alloc.allocateCopy(Array2);<br>
+  EXPECT_TRUE(Array1.equals(Array1c));<br>
+  EXPECT_NE(Array1.data(), Array1c.data());<br>
+  EXPECT_TRUE(Array2.equals(Array2c));<br>
+  EXPECT_NE(Array2.data(), Array2c.data());<br>
+}<br>
+<br>
+<br>
+<br>
 }  // anonymous namespace<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>