toAppendDelimited, toDelimited
authorTudor Bosman <tudorb@fb.com>
Sat, 20 Apr 2013 20:07:39 +0000 (13:07 -0700)
committerSara Golemon <sgolemon@fb.com>
Mon, 20 May 2013 18:01:26 +0000 (11:01 -0700)
Test Plan: test added

Reviewed By: delong.j@fb.com

FB internal diff: D783100

folly/Conv.h
folly/test/ConvTest.cpp

index c8360a6d7675b21f1506404c372cde0cd77eb10c..4d14a559ef92804ee626e4f71dfabefc27def8fb 100644 (file)
@@ -476,6 +476,38 @@ typename std::enable_if<detail::IsSomeString<Tgt>::value>::type
 toAppend(Tgt* result) {
 }
 
+/**
+ * Variadic base case: do nothing.
+ */
+template <class Delimiter, class Tgt>
+typename std::enable_if<detail::IsSomeString<Tgt>::value>::type
+toAppendDelim(const Delimiter& delim, Tgt* result) {
+}
+
+/**
+ * 1 element: same as toAppend.
+ */
+template <class Delimiter, class T, class Tgt>
+typename std::enable_if<detail::IsSomeString<Tgt>::value>::type
+toAppendDelim(const Delimiter& delim, const T& v, Tgt* tgt) {
+  toAppend(v, tgt);
+}
+
+/**
+ * Append to string with a delimiter in between elements.
+ */
+template <class Delimiter, class T, class... Ts>
+typename std::enable_if<sizeof...(Ts) >= 2
+  && detail::IsSomeString<
+  typename std::remove_pointer<
+    typename std::tuple_element<
+      sizeof...(Ts) - 1, std::tuple<Ts...>
+      >::type>::type>::value>::type
+toAppendDelim(const Delimiter& delim, const T& v, const Ts&... vs) {
+  toAppend(v, delim, detail::getLastElement(vs...));
+  toAppendDelim(delim, vs...);
+}
+
 /**
  * to<SomeString>(v1, v2, ...) uses toAppend() (see below) as back-end
  * for all types.
@@ -488,6 +520,18 @@ to(const Ts&... vs) {
   return result;
 }
 
+/**
+ * toDelim<SomeString>(delim, v1, v2, ...) uses toAppendDelim() as
+ * back-end for all types.
+ */
+template <class Tgt, class Delim, class... Ts>
+typename std::enable_if<detail::IsSomeString<Tgt>::value, Tgt>::type
+toDelim(const Delim& delim, const Ts&... vs) {
+  Tgt result;
+  toAppendDelim(delim, vs..., &result);
+  return result;
+}
+
 /*******************************************************************************
  * Conversions from string types to integral types.
  ******************************************************************************/
index 7dd6d0a4b87f8205bf76a69a62f7891d7d44a345..f48c69c39e34838a89f9c63355f54c69bb854884 100644 (file)
@@ -403,6 +403,22 @@ void testVariadicTo() {
   EXPECT_EQ(s, "Lorem ipsum 1234 dolor amet 567.89.");
 }
 
+template <class String>
+void testVariadicToDelim() {
+  String s;
+  toAppendDelim(":", &s);
+  toAppendDelim(
+      ":", "Lorem ipsum ", 1234, String(" dolor amet "), 567.89, '!', &s);
+  EXPECT_EQ(s, "Lorem ipsum :1234: dolor amet :567.89:!");
+
+  s = toDelim<String>(':');
+  EXPECT_TRUE(s.empty());
+
+  s = toDelim<String>(
+      ":", "Lorem ipsum ", nullptr, 1234, " dolor amet ", 567.89, '.');
+  EXPECT_EQ(s, "Lorem ipsum ::1234: dolor amet :567.89:.");
+}
+
 TEST(Conv, NullString) {
   string s1 = to<string>((char *) NULL);
   EXPECT_TRUE(s1.empty());
@@ -415,6 +431,11 @@ TEST(Conv, VariadicTo) {
   testVariadicTo<fbstring>();
 }
 
+TEST(Conv, VariadicToDelim) {
+  testVariadicToDelim<string>();
+  testVariadicToDelim<fbstring>();
+}
+
 template <class String>
 void testDoubleToString() {
   EXPECT_EQ(to<string>(0.0), "0");