Commit a7937a66 authored by HC Zhu's avatar HC Zhu Committed by Facebook Github Bot

Allow std::ignore in split()

Summary:
This allows a caller to throw away unwanted parts e.g.

```
std::string user;
folly::split('/', "ads_lla/admarket/adfox", std::ignore, user, std::ignore);

```

Reviewed By: yfeldblum

Differential Revision: D10057247

fbshipit-source-id: 8198d4cb207bbd2007635db1e5796759dccf367c
parent 061ea836
......@@ -332,16 +332,25 @@ inline char prepareDelim(char c) {
return c;
}
template <class OutputType>
void toOrIgnore(StringPiece input, OutputType& output) {
output = folly::to<OutputType>(input);
}
inline void toOrIgnore(StringPiece, decltype(std::ignore)&) {}
template <bool exact, class Delim, class OutputType>
bool splitFixed(const Delim& delimiter, StringPiece input, OutputType& output) {
static_assert(
exact || std::is_same<OutputType, StringPiece>::value ||
IsSomeString<OutputType>::value,
"split<false>() requires that the last argument be a string type");
IsSomeString<OutputType>::value ||
std::is_same<OutputType, decltype(std::ignore)>::value,
"split<false>() requires that the last argument be a string type "
"or std::ignore");
if (exact && UNLIKELY(std::string::npos != input.find(delimiter))) {
return false;
}
output = folly::to<OutputType>(input);
toOrIgnore(input, output);
return true;
}
......@@ -359,7 +368,7 @@ bool splitFixed(
StringPiece tail(
input.begin() + cut + detail::delimSize(delimiter), input.end());
if (LIKELY(splitFixed<exact>(delimiter, tail, outTail...))) {
outHead = folly::to<OutputType>(head);
toOrIgnore(head, outHead);
return true;
}
return false;
......
......@@ -479,6 +479,9 @@ namespace detail {
template <typename Void, typename OutputType>
struct IsConvertible : std::false_type {};
template <>
struct IsConvertible<void, decltype(std::ignore)> : std::true_type {};
template <typename OutputType>
struct IsConvertible<
void_t<decltype(parseTo(StringPiece{}, std::declval<OutputType&>()))>,
......
......@@ -19,6 +19,7 @@
#endif
#include <folly/String.h>
#include <tuple>
#include <cinttypes>
#include <set>
......@@ -954,6 +955,20 @@ TEST(Split, fixed_convert) {
// Enable verifying that a line only contains one field
EXPECT_TRUE(folly::split(' ', "hello", a));
EXPECT_FALSE(folly::split(' ', "hello world", a));
// Test cases with std::ignore.
EXPECT_TRUE(folly::split(':', "a:13:14.7:b", std::ignore, b, c, d));
EXPECT_EQ(13, b);
EXPECT_NEAR(14.7, c, 1e-10);
EXPECT_EQ("b", d);
EXPECT_TRUE(folly::split(':', "a:13:14.7:b", std::ignore, b, c, std::ignore));
EXPECT_EQ(13, b);
EXPECT_NEAR(14.7, c, 1e-10);
EXPECT_TRUE(folly::split<false>(':', "a:13:14.7:b", a, b, std::ignore));
EXPECT_EQ("a", a);
EXPECT_EQ(13, b);
}
namespace my {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment