blob: 384f24a5c4830e2c6dedb0620315b93ca09f315d [file] [log] [blame]
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2017 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
/** \file
* \brief Backport of ostream_joiner from the Library Fundamentals v2 TS
* \sa http://en.cppreference.com/w/cpp/experimental/ostream_joiner
*/
#ifndef NDN_UTIL_BACKPORTS_OSTREAM_JOINER_HPP
#define NDN_UTIL_BACKPORTS_OSTREAM_JOINER_HPP
#include "../common.hpp"
#if __cplusplus >= 201402L
# ifdef __has_include
# if __has_include(<experimental/iterator>)
# include <experimental/iterator>
# if __cpp_lib_experimental_ostream_joiner >= 201411
# define NDN_CXX_HAVE_EXPERIMENTAL_OSTREAM_JOINER
# endif
# endif
# endif
#endif
#ifdef NDN_CXX_HAVE_EXPERIMENTAL_OSTREAM_JOINER
namespace ndn {
using std::experimental::ostream_joiner;
using std::experimental::make_ostream_joiner;
} // namespace ndn
#else
#include <iterator>
namespace ndn {
template<typename DelimT,
typename CharT = char,
typename Traits = std::char_traits<CharT>>
class ostream_joiner
{
public:
typedef CharT char_type;
typedef Traits traits_type;
typedef std::basic_ostream<CharT, Traits> ostream_type;
typedef std::output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
ostream_joiner(ostream_type& os, const DelimT& delimiter)
noexcept(std::is_nothrow_copy_constructible<DelimT>::value)
: m_os(std::addressof(os)), m_delim(delimiter)
{
}
ostream_joiner(ostream_type& os, DelimT&& delimiter)
noexcept(std::is_nothrow_move_constructible<DelimT>::value)
: m_os(std::addressof(os)), m_delim(std::move(delimiter))
{
}
template<typename T>
ostream_joiner&
operator=(const T& value)
{
if (!m_isFirst) {
*m_os << m_delim;
}
m_isFirst = false;
*m_os << value;
return *this;
}
ostream_joiner&
operator*() noexcept
{
return *this;
}
ostream_joiner&
operator++() noexcept
{
return *this;
}
ostream_joiner&
operator++(int) noexcept
{
return *this;
}
private:
ostream_type* m_os;
DelimT m_delim;
bool m_isFirst = true;
};
template<typename CharT, typename Traits, typename DelimT>
inline ostream_joiner<typename std::decay<DelimT>::type, CharT, Traits>
make_ostream_joiner(std::basic_ostream<CharT, Traits>& os, DelimT&& delimiter)
{
return {os, std::forward<DelimT>(delimiter)};
}
} // namespace ndn
#endif // NDN_CXX_HAVE_EXPERIMENTAL_OSTREAM_JOINER
#endif // NDN_UTIL_BACKPORTS_OSTREAM_JOINER_HPP