Allow for different iterator types for arg_join

With  C++20,  and already  in  the  ranges-v3  library (and  many  other
projects); the iterators that can  be compared within algorithms may not
be the same type.  Even `begin` and `end` iterators may  not be the same
time, but still correspond to the same range.

This patch allows for a "sentinel" type.
This commit is contained in:
Matthew Parnell 2019-12-04 17:29:11 +00:00
parent 31ea064e41
commit b2917bbeea

View File

@ -3217,22 +3217,22 @@ template <typename T> inline const void* ptr(const std::shared_ptr<T>& p) {
return p.get(); return p.get();
} }
template <typename It, typename Char> template <typename It, typename S, typename Char>
struct arg_join : internal::view { struct arg_join : internal::view {
It first; It first;
It last; S last;
basic_string_view<Char> sep; basic_string_view<Char> sep;
arg_join(It b, It e, basic_string_view<Char> s) : first(b), last(e), sep(s) {} arg_join(It f, S l, basic_string_view<Char> s) : first(f), last(l), sep(s) {}
It begin() const { return first; } It begin() const { return first; }
It end() const { return last; } S end() const { return last; }
}; };
template <typename It, typename Char> template <typename It, typename S, typename Char>
struct formatter<arg_join<It, Char>, Char> struct formatter<arg_join<It, S, Char>, Char>
: formatter<typename std::iterator_traits<It>::value_type, Char> { : formatter<typename std::iterator_traits<It>::value_type, Char> {
template <typename FormatContext> template <typename FormatContext>
auto format(const arg_join<It, Char>& value, FormatContext& ctx) auto format(const arg_join<It, S, Char>& value, FormatContext& ctx)
-> decltype(ctx.out()) { -> decltype(ctx.out()) {
using base = formatter<typename std::iterator_traits<It>::value_type, Char>; using base = formatter<typename std::iterator_traits<It>::value_type, Char>;
auto it = value.begin(); auto it = value.begin();
@ -3253,13 +3253,13 @@ struct formatter<arg_join<It, Char>, Char>
Returns an object that formats the iterator range `[begin, end)` with elements Returns an object that formats the iterator range `[begin, end)` with elements
separated by `sep`. separated by `sep`.
*/ */
template <typename It> template <typename It, typename S = It>
arg_join<It, char> join(It begin, It end, string_view sep) { arg_join<It, S, char> join(It begin, S end, string_view sep) {
return {begin, end, sep}; return {begin, end, sep};
} }
template <typename It> template <typename It, typename S = It>
arg_join<It, wchar_t> join(It begin, It end, wstring_view sep) { arg_join<It, S, wchar_t> join(It begin, S end, wstring_view sep) {
return {begin, end, sep}; return {begin, end, sep};
} }
@ -3275,13 +3275,15 @@ arg_join<It, wchar_t> join(It begin, It end, wstring_view sep) {
\endrst \endrst
*/ */
template <typename Range> template <typename Range>
arg_join<internal::iterator_t<const Range>, char> arg_join<internal::iterator_t<const Range>, internal::iterator_t<const Range>,
char>
join(const Range& range, string_view sep) { join(const Range& range, string_view sep) {
return join(std::begin(range), std::end(range), sep); return join(std::begin(range), std::end(range), sep);
} }
template <typename Range> template <typename Range>
arg_join<internal::iterator_t<const Range>, wchar_t> arg_join<internal::iterator_t<const Range>, internal::iterator_t<const Range>,
wchar_t>
join(const Range& range, wstring_view sep) { join(const Range& range, wstring_view sep) {
return join(std::begin(range), std::end(range), sep); return join(std::begin(range), std::end(range), sep);
} }