Make join() handle non-const-only begin/end ranges (#1786)
See fmtlib/fmt#1784. Add tests that demonstrate the problem and check obvious variations.
This commit is contained in:
parent
d69e2da221
commit
febffa4e64
@ -3420,15 +3420,14 @@ arg_join<It, Sentinel, wchar_t> join(It begin, Sentinel end, wstring_view sep) {
|
||||
\endrst
|
||||
*/
|
||||
template <typename Range>
|
||||
arg_join<detail::iterator_t<const Range>, detail::sentinel_t<const Range>, char>
|
||||
join(const Range& range, string_view sep) {
|
||||
arg_join<detail::iterator_t<Range>, detail::sentinel_t<Range>, char> join(
|
||||
Range&& range, string_view sep) {
|
||||
return join(std::begin(range), std::end(range), sep);
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
arg_join<detail::iterator_t<const Range>, detail::sentinel_t<const Range>,
|
||||
wchar_t>
|
||||
join(const Range& range, wstring_view sep) {
|
||||
arg_join<detail::iterator_t<Range>, detail::sentinel_t<Range>, wchar_t> join(
|
||||
Range&& range, wstring_view sep) {
|
||||
return join(std::begin(range), std::end(range), sep);
|
||||
}
|
||||
|
||||
|
@ -153,3 +153,37 @@ TEST(RangesTest, JoinSentinel) {
|
||||
EXPECT_EQ("{'h', 'e', 'l', 'l', 'o'}", fmt::format("{}", hello));
|
||||
EXPECT_EQ("h_e_l_l_o", fmt::format("{}", fmt::join(hello, "_")));
|
||||
}
|
||||
|
||||
// A range that provides non-const only begin()/end() to test fmt::join handles
|
||||
// that
|
||||
//
|
||||
// Some ranges (eg those produced by range-v3's views::filter()) can cache
|
||||
// information during iteration so they only provide non-const begin()/end().
|
||||
template <typename T> class non_const_only_range {
|
||||
private:
|
||||
std::vector<T> vec;
|
||||
|
||||
public:
|
||||
using const_iterator = typename ::std::vector<T>::const_iterator;
|
||||
|
||||
template <typename... Args>
|
||||
explicit non_const_only_range(Args&&... args)
|
||||
: vec(::std::forward<Args>(args)...) {}
|
||||
|
||||
const_iterator begin() { return vec.begin(); }
|
||||
const_iterator end() { return vec.end(); }
|
||||
};
|
||||
|
||||
TEST(RangesTest, JoinRange) {
|
||||
non_const_only_range<int> x(3, 0);
|
||||
EXPECT_EQ("0,0,0", fmt::format("{}", fmt::join(x, ",")));
|
||||
EXPECT_EQ("0,0,0",
|
||||
fmt::format("{}", fmt::join(non_const_only_range<int>(3, 0), ",")));
|
||||
|
||||
std::vector<int> y(3, 0);
|
||||
EXPECT_EQ("0,0,0", fmt::format("{}", fmt::join(y, ",")));
|
||||
EXPECT_EQ("0,0,0", fmt::format("{}", fmt::join(std::vector<int>(3, 0), ",")));
|
||||
|
||||
const std::vector<int> z(3, 0);
|
||||
EXPECT_EQ("0,0,0", fmt::format("{}", fmt::join(z, ",")));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user