ostream-joiner.hpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013-2021 Regents of the University of California.
4  *
5  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6  *
7  * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8  * terms of the GNU Lesser General Public License as published by the Free Software
9  * Foundation, either version 3 of the License, or (at your option) any later version.
10  *
11  * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13  * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14  *
15  * You should have received copies of the GNU General Public License and GNU Lesser
16  * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17  * <http://www.gnu.org/licenses/>.
18  *
19  * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20  */
21 
27 #ifndef NDN_CXX_UTIL_OSTREAM_JOINER_HPP
28 #define NDN_CXX_UTIL_OSTREAM_JOINER_HPP
29 
31 
32 #if NDN_CXX_HAS_INCLUDE(<experimental/iterator>)
33 # include <experimental/iterator>
34 # if __cpp_lib_experimental_ostream_joiner >= 201411
35 # define NDN_CXX_HAVE_EXPERIMENTAL_OSTREAM_JOINER
36 # endif
37 #endif
38 
39 #ifdef NDN_CXX_HAVE_EXPERIMENTAL_OSTREAM_JOINER
40 
41 namespace ndn {
42 using std::experimental::ostream_joiner;
44 } // namespace ndn
45 
46 #else
47 
48 #include <iterator>
49 
50 namespace ndn {
51 
52 template<typename DelimT,
53  typename CharT = char,
54  typename Traits = std::char_traits<CharT>>
56 {
57 public:
58  typedef CharT char_type;
59  typedef Traits traits_type;
60  typedef std::basic_ostream<CharT, Traits> ostream_type;
61  typedef std::output_iterator_tag iterator_category;
62  typedef void value_type;
63  typedef void difference_type;
64  typedef void pointer;
65  typedef void reference;
66 
67  ostream_joiner(ostream_type& os, const DelimT& delimiter)
68  noexcept(std::is_nothrow_copy_constructible<DelimT>::value)
69  : m_os(std::addressof(os)), m_delim(delimiter)
70  {
71  }
72 
73  ostream_joiner(ostream_type& os, DelimT&& delimiter)
74  noexcept(std::is_nothrow_move_constructible<DelimT>::value)
75  : m_os(std::addressof(os)), m_delim(std::move(delimiter))
76  {
77  }
78 
79  template<typename T>
81  operator=(const T& value)
82  {
83  if (!m_isFirst) {
84  *m_os << m_delim;
85  }
86  m_isFirst = false;
87  *m_os << value;
88  return *this;
89  }
90 
92  operator*() noexcept
93  {
94  return *this;
95  }
96 
98  operator++() noexcept
99  {
100  return *this;
101  }
102 
104  operator++(int) noexcept
105  {
106  return *this;
107  }
108 
109 private:
110  ostream_type* m_os;
111  DelimT m_delim;
112  bool m_isFirst = true;
113 };
114 
115 template<typename CharT, typename Traits, typename DelimT>
116 inline ostream_joiner<std::decay_t<DelimT>, CharT, Traits>
117 make_ostream_joiner(std::basic_ostream<CharT, Traits>& os, DelimT&& delimiter)
118 {
119  return {os, std::forward<DelimT>(delimiter)};
120 }
121 
122 } // namespace ndn
123 
124 #endif // NDN_CXX_HAVE_EXPERIMENTAL_OSTREAM_JOINER
125 #endif // NDN_CXX_UTIL_OSTREAM_JOINER_HPP
std::basic_ostream< CharT, Traits > ostream_type
ostream_joiner(ostream_type &os, const DelimT &delimiter) noexcept(std::is_nothrow_copy_constructible< DelimT >::value)
ostream_joiner & operator*() noexcept
ostream_joiner(ostream_type &os, DelimT &&delimiter) noexcept(std::is_nothrow_move_constructible< DelimT >::value)
ostream_joiner & operator++(int) noexcept
std::output_iterator_tag iterator_category
ostream_joiner & operator++() noexcept
ostream_joiner & operator=(const T &value)
Definition: data.cpp:25
ostream_joiner< std::decay_t< DelimT >, CharT, Traits > make_ostream_joiner(std::basic_ostream< CharT, Traits > &os, DelimT &&delimiter)