Make join() handle non-const-only begin/end ranges
See fmtlib/fmt#1784. Add tests that demonstrate the problem and check obvious variations.
This commit is contained in:
parent
d69e2da221
commit
a018b09aab
@ -3420,15 +3420,15 @@ 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>,
|
||||
arg_join<detail::iterator_t<Range>, detail::sentinel_t<Range>,
|
||||
wchar_t>
|
||||
join(const Range& range, wstring_view sep) {
|
||||
join(Range&& range, wstring_view sep) {
|
||||
return join(std::begin(range), std::end(range), sep);
|
||||
}
|
||||
|
||||
|
||||
@ -153,3 +153,39 @@ 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