blob: 75d53dda84f12829eb47ae1f21edc4f756bb4679 [file] [log] [blame]
Davide Pesaventocf415762017-02-25 23:46:47 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesaventoba4fbbe2017-07-03 01:06:30 -04002/*
Davide Pesaventocf415762017-02-25 23:46:47 -05003 * Copyright (c) 2013-2017 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
22/** \file
23 * \brief Backport of ostream_joiner from the Library Fundamentals v2 TS
24 * \sa http://en.cppreference.com/w/cpp/experimental/ostream_joiner
25 */
26
27#ifndef NDN_UTIL_BACKPORTS_OSTREAM_JOINER_HPP
28#define NDN_UTIL_BACKPORTS_OSTREAM_JOINER_HPP
29
Davide Pesavento1c597a12017-10-06 15:34:24 -040030#include "backports.hpp"
Davide Pesaventocf415762017-02-25 23:46:47 -050031
Davide Pesavento1c597a12017-10-06 15:34:24 -040032#if (__cplusplus >= 201402L) && 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
Davide Pesaventocf415762017-02-25 23:46:47 -050036# endif
37#endif
38
39#ifdef NDN_CXX_HAVE_EXPERIMENTAL_OSTREAM_JOINER
40
41namespace ndn {
42using std::experimental::ostream_joiner;
43using std::experimental::make_ostream_joiner;
44} // namespace ndn
45
46#else
47
48#include <iterator>
49
50namespace ndn {
51
52template<typename DelimT,
53 typename CharT = char,
54 typename Traits = std::char_traits<CharT>>
55class ostream_joiner
56{
57public:
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>
80 ostream_joiner&
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
91 ostream_joiner&
92 operator*() noexcept
93 {
94 return *this;
95 }
96
97 ostream_joiner&
98 operator++() noexcept
99 {
100 return *this;
101 }
102
103 ostream_joiner&
104 operator++(int) noexcept
105 {
106 return *this;
107 }
108
109private:
110 ostream_type* m_os;
111 DelimT m_delim;
112 bool m_isFirst = true;
113};
114
115template<typename CharT, typename Traits, typename DelimT>
116inline ostream_joiner<typename std::decay<DelimT>::type, CharT, Traits>
117make_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_UTIL_BACKPORTS_OSTREAM_JOINER_HPP