openMSX
join.hh
Go to the documentation of this file.
1 #ifndef JOIN_HH
2 #define JOIN_HH
3 
4 #include <iostream>
5 #include <iterator>
6 #include <sstream>
7 #include <string>
8 #include <utility>
9 
10 namespace detail {
11 
12 template<typename Collection, typename Separator>
13 class Joiner
14 {
15 public:
16  Joiner(Collection&& col_, Separator&& sep_)
17  : col(std::forward<Collection>(col_))
18  , sep(std::forward<Separator>(sep_))
19  {
20  }
21 
22  friend std::ostream& operator<<(std::ostream& os, const Joiner& joiner)
23  {
24  return joiner.execute(os);
25  }
26 
27  [[nodiscard]] operator std::string() const
28  {
29  std::ostringstream os;
30  execute(os);
31  return os.str();
32  }
33 
34 private:
35  template<typename OutputStream>
36  OutputStream& execute(OutputStream& os) const
37  {
38  auto first = std::begin(col);
39  auto last = std::end (col);
40  if (first != last) {
41  goto print;
42  while (first != last) {
43  os << sep;
44  print: os << *first;
45  ++first;
46  }
47  }
48  return os;
49  }
50 
51 private:
52  Collection col;
53  Separator sep;
54 };
55 
56 } // namespace detail
57 
58 
59 template<typename Collection, typename Separator>
60 [[nodiscard]] detail::Joiner<Collection, Separator> join(Collection&& col, Separator&& sep)
61 {
62  return { std::forward<Collection>(col), std::forward<Separator>(sep) };
63 }
64 
65 #endif
STL namespace.
friend std::ostream & operator<<(std::ostream &os, const Joiner &joiner)
Definition: join.hh:22
Definition: join.hh:10
detail::Joiner< Collection, Separator > join(Collection &&col, Separator &&sep)
Definition: join.hh:60
Joiner(Collection &&col_, Separator &&sep_)
Definition: join.hh:16