[PATCH] D24880: Add StringExtras join_items function

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 23 13:15:54 PDT 2016


zturner updated this revision to Diff 72337.
zturner added a comment.

Added missing unit test file.


https://reviews.llvm.org/D24880

Files:
  include/llvm/ADT/StringExtras.h
  unittests/ADT/CMakeLists.txt

Index: unittests/ADT/CMakeLists.txt
===================================================================
--- unittests/ADT/CMakeLists.txt
+++ unittests/ADT/CMakeLists.txt
@@ -53,6 +53,7 @@
   SparseBitVectorTest.cpp
   SparseMultiSetTest.cpp
   SparseSetTest.cpp
+  StringExtrasTest.cpp
   StringMapTest.cpp
   StringRefTest.cpp
   TinyPtrVectorTest.cpp
Index: include/llvm/ADT/StringExtras.h
===================================================================
--- include/llvm/ADT/StringExtras.h
+++ include/llvm/ADT/StringExtras.h
@@ -155,6 +155,8 @@
 /// it if it is not printable or if it is an escape char.
 void PrintEscapedString(StringRef Name, raw_ostream &Out);
 
+namespace detail {
+
 template <typename IteratorT>
 inline std::string join_impl(IteratorT Begin, IteratorT End,
                              StringRef Separator, std::input_iterator_tag) {
@@ -168,33 +170,58 @@
     S += (*Begin);
   }
   return S;
-}
+  }
 
-template <typename IteratorT>
-inline std::string join_impl(IteratorT Begin, IteratorT End,
-                             StringRef Separator, std::forward_iterator_tag) {
-  std::string S;
-  if (Begin == End)
+  template <typename IteratorT>
+  inline std::string join_impl(IteratorT Begin, IteratorT End,
+                               StringRef Separator, std::forward_iterator_tag) {
+    std::string S;
+    if (Begin == End)
+      return S;
+
+    size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
+    for (IteratorT I = Begin; I != End; ++I)
+      Len += (*Begin).size();
+    S.reserve(Len);
+    S += (*Begin);
+    while (++Begin != End) {
+      S += Separator;
+      S += (*Begin);
+    }
     return S;
+  }
 
-  size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
-  for (IteratorT I = Begin; I != End; ++I)
-    Len += (*Begin).size();
-  S.reserve(Len);
-  S += (*Begin);
-  while (++Begin != End) {
-    S += Separator;
-    S += (*Begin);
+  inline void join_items_impl(std::string &Result, StringRef Separator) {}
+
+  template <typename Arg>
+  inline void join_items_impl(std::string &Result, StringRef Separator,
+                              const Arg &Item) {
+    Result += Item;
+  }
+
+  template <typename Arg1, typename Arg2, typename... Args>
+  inline void join_items_impl(std::string &Result, StringRef Separator,
+                              const Arg1 &A1, const Arg2 &A2,
+                              Args &&... Items) {
+    Result += A1;
+    Result += Separator;
+    join_items_impl(Result, Separator, A2, std::forward<Args>(Items)...);
   }
-  return S;
 }
 
 /// Joins the strings in the range [Begin, End), adding Separator between
 /// the elements.
 template <typename IteratorT>
 inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) {
   typedef typename std::iterator_traits<IteratorT>::iterator_category tag;
-  return join_impl(Begin, End, Separator, tag());
+  return detail::join_impl(Begin, End, Separator, tag());
+}
+
+template <typename... Args>
+inline std::string join_items(StringRef Separator, Args &&... Items) {
+  std::string Result;
+  detail::join_items_impl(Result, Separator, std::forward<Args>(Items)...);
+  return Result;
 }
 
 } // End llvm namespace


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D24880.72337.patch
Type: text/x-patch
Size: 3220 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160923/0dd8927f/attachment.bin>


More information about the llvm-commits mailing list