Commit 687b7288 authored by Tom Jackson's avatar Tom Jackson Committed by Facebook Github Bot

byLine(istream), with partial consumption

Summary:
Without this, `folly::gen`'s other `byLine()` implementations only
support a single read pass (usually through the whole input file) without
support for different formats through the file.

Reviewed By: yfeldblum

Differential Revision: D9540396

fbshipit-source-id: 6539851a70aed9a88d3c61986a459f60dfb7be5b
parent ed0a63ed
/*
* Copyright 2018-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <istream>
#include <string>
#include <folly/gen/Core.h>
namespace folly {
namespace gen {
namespace detail {
/**
* Generates lines by calling std::getline() on a given istream.
*/
class IStreamByLine : public GenImpl<std::string&&, IStreamByLine> {
public:
IStreamByLine(std::istream& in) : in_(in) {}
template <class Body>
bool apply(Body&& body) const {
for (std::string line; std::getline(in_, line);) {
if (!body(std::move(line))) {
return false;
}
}
return true;
}
// Technically, there could be infinite files (e.g. /dev/random), but people
// who open those can do so at their own risk.
static constexpr bool infinite = false;
private:
std::istream& in_;
};
} // namespace detail
inline detail::IStreamByLine byLine(std::istream& in) {
return detail::IStreamByLine(in);
}
} // namespace gen
} // namespace folly
/*
* Copyright 2014-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <folly/gen/IStream.h>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
#include <folly/gen/Base.h>
#include <folly/gen/String.h>
#include <folly/portability/GTest.h>
namespace folly {
namespace gen {
// Test mixed consumption of std::istream with and without folly::gen, and
// demonstrates partial consumption of input.
TEST(IStream, ByLine) {
std::stringstream in(
"2\n" // Count applies to both below groups.
"1\tred\n"
"3\tblue\n"
"3.4\t5.6\t7.8\n"
"1.1\t2.2\t3.3\n");
size_t n;
in >> n;
in.get(); // Consume trailing newline
auto colors = byLine(in) | take(n) | eachToPair<int, std::string>('\t') |
as<std::vector>();
auto coords = byLine(in) | take(n) | eachToTuple<float, float, float>('\t') |
as<std::vector>();
EXPECT_EQ(
colors,
(std::vector<std::pair<int, std::string>>{
{1, "red"},
{3, "blue"},
}));
EXPECT_EQ(
coords,
(std::vector<std::tuple<float, float, float>>({
std::tuple<float, float, float>{3.4f, 5.6f, 7.8f},
std::tuple<float, float, float>{1.1f, 2.2f, 3.3f},
})));
}
} // namespace gen
} // namespace folly
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