+ const bool ignoreEmpty = false);
+
+/*
+ * Split a string into a fixed number of string pieces and/or numeric types
+ * by delimiter. Conversions are supported for any type which folly:to<> can
+ * target, including all overloads of parseTo(). Returns 'true' if the fields
+ * were all successfully populated. Returns 'false' if there were too few
+ * fields in the input, or too many fields if exact=true. Casting exceptions
+ * will not be caught.
+ *
+ * Examples:
+ *
+ * folly::StringPiece name, key, value;
+ * if (folly::split('\t', line, name, key, value))
+ * ...
+ *
+ * folly::StringPiece name;
+ * double value;
+ * int id;
+ * if (folly::split('\t', line, name, value, id))
+ * ...
+ *
+ * The 'exact' template parameter specifies how the function behaves when too
+ * many fields are present in the input string. When 'exact' is set to its
+ * default value of 'true', a call to split will fail if the number of fields in
+ * the input string does not exactly match the number of output parameters
+ * passed. If 'exact' is overridden to 'false', all remaining fields will be
+ * stored, unsplit, in the last field, as shown below:
+ *
+ * folly::StringPiece x, y.
+ * if (folly::split<false>(':', "a:b:c", x, y))
+ * assert(x == "a" && y == "b:c");
+ *
+ * Note that this will likely not work if the last field's target is of numeric
+ * type, in which case folly::to<> will throw an exception.
+ */
+template <class T, class Enable = void>
+struct IsSomeVector {
+ enum { value = false };
+};
+
+template <class T>
+struct IsSomeVector<std::vector<T>, void> {
+ enum { value = true };
+};
+
+template <class T>
+struct IsSomeVector<fbvector<T>, void> {
+ enum { value = true };
+};
+
+template <class T, class Enable = void>
+struct IsConvertible {
+ enum { value = false };
+};
+
+template <class T>
+struct IsConvertible<
+ T,
+ decltype(static_cast<void>(
+ parseTo(std::declval<folly::StringPiece>(), std::declval<T&>())))> {
+ enum { value = true };
+};
+
+template <class... Types>
+struct AllConvertible;
+
+template <class Head, class... Tail>
+struct AllConvertible<Head, Tail...> {
+ enum { value = IsConvertible<Head>::value && AllConvertible<Tail...>::value };
+};
+
+template <>
+struct AllConvertible<> {
+ enum { value = true };
+};
+
+static_assert(AllConvertible<float>::value, "");
+static_assert(AllConvertible<int>::value, "");
+static_assert(AllConvertible<bool>::value, "");
+static_assert(AllConvertible<int>::value, "");
+static_assert(!AllConvertible<std::vector<int>>::value, "");
+
+template <bool exact = true, class Delim, class... OutputTypes>
+typename std::enable_if<
+ AllConvertible<OutputTypes...>::value && sizeof...(OutputTypes) >= 1,
+ bool>::type
+split(const Delim& delimiter, StringPiece input, OutputTypes&... outputs);