[PATCH] D24880: Add StringExtras join_items function
Zachary Turner via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 23 13:13:40 PDT 2016
zturner created this revision.
zturner added reviewers: majnemer, sanjoy.
zturner added a subscriber: llvm-commits.
Herald added subscribers: mgorny, beanz.
There's already `llvm::join` which is useful for joining a container of items. But there is no way to join items of disparate types, or types who are not in a container for whatever reason.
For example, if you have a `std::string`, a `llvm::StringRef`, and a `const char *`, you would have to manually construct a container to put them in before joining them, which is inconvnient.
This adds a variadic `join_items` function for this purpose.
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.72336.patch
Type: text/x-patch
Size: 3220 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160923/01d33203/attachment.bin>
More information about the llvm-commits
mailing list