10b57cec5SDimitry Andric// -*- C++ -*- 2*349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 30b57cec5SDimitry Andric// 40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 70b57cec5SDimitry Andric// 80b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 90b57cec5SDimitry Andric 100b57cec5SDimitry Andric#ifndef _LIBCPP_EXPERIMENTAL_ITERATOR 110b57cec5SDimitry Andric#define _LIBCPP_EXPERIMENTAL_ITERATOR 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric/* 140b57cec5SDimitry Andricnamespace std { 150b57cec5SDimitry Andric namespace experimental { 160b57cec5SDimitry Andric inline namespace fundamentals_v2 { 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric template <class DelimT, class charT = char, class traits = char_traits<charT>> 190b57cec5SDimitry Andric class ostream_joiner { 200b57cec5SDimitry Andric public: 210b57cec5SDimitry Andric typedef charT char_type; 220b57cec5SDimitry Andric typedef traits traits_type; 230b57cec5SDimitry Andric typedef basic_ostream<charT, traits> ostream_type; 240b57cec5SDimitry Andric typedef output_iterator_tag iterator_category; 250b57cec5SDimitry Andric typedef void value_type; 260b57cec5SDimitry Andric typedef void difference_type; 270b57cec5SDimitry Andric typedef void pointer; 280b57cec5SDimitry Andric typedef void reference; 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric ostream_joiner(ostream_type& s, const DelimT& delimiter); 310b57cec5SDimitry Andric ostream_joiner(ostream_type& s, DelimT&& delimiter); 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric template<typename T> 340b57cec5SDimitry Andric ostream_joiner& operator=(const T& value); 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric ostream_joiner& operator*() noexcept; 370b57cec5SDimitry Andric ostream_joiner& operator++() noexcept; 380b57cec5SDimitry Andric ostream_joiner& operator++(int) noexcept; 390b57cec5SDimitry Andric private: 400b57cec5SDimitry Andric ostream_type* out_stream; // exposition only 410b57cec5SDimitry Andric DelimT delim; // exposition only 420b57cec5SDimitry Andric bool first_element; // exposition only 430b57cec5SDimitry Andric }; 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric template <class charT, class traits, class DelimT> 460b57cec5SDimitry Andric ostream_joiner<decay_t<DelimT>, charT, traits> 470b57cec5SDimitry Andric make_ostream_joiner(basic_ostream<charT, traits>& os, DelimT&& delimiter); 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric } // inline namespace fundamentals_v2 500b57cec5SDimitry Andric } // namespace experimental 510b57cec5SDimitry Andric} // namespace std 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric*/ 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric#include <experimental/__config> 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11 580b57cec5SDimitry Andric 59fe6060f1SDimitry Andric#include <__memory/addressof.h> 60fe6060f1SDimitry Andric#include <__utility/move.h> 61fe6060f1SDimitry Andric#include <__utility/forward.h> 620b57cec5SDimitry Andric#include <iterator> 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_LFTS 650b57cec5SDimitry Andric 660b57cec5SDimitry Andrictemplate <class _Delim, class _CharT = char, class _Traits = char_traits<_CharT>> 670b57cec5SDimitry Andricclass ostream_joiner { 680b57cec5SDimitry Andricpublic: 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric typedef _CharT char_type; 710b57cec5SDimitry Andric typedef _Traits traits_type; 720b57cec5SDimitry Andric typedef basic_ostream<char_type,traits_type> ostream_type; 730b57cec5SDimitry Andric typedef output_iterator_tag iterator_category; 740b57cec5SDimitry Andric typedef void value_type; 750b57cec5SDimitry Andric typedef void difference_type; 760b57cec5SDimitry Andric typedef void pointer; 770b57cec5SDimitry Andric typedef void reference; 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric ostream_joiner(ostream_type& __os, _Delim&& __d) 800b57cec5SDimitry Andric : __output_iter(_VSTD::addressof(__os)), __delim(_VSTD::move(__d)), __first(true) {} 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric ostream_joiner(ostream_type& __os, const _Delim& __d) 830b57cec5SDimitry Andric : __output_iter(_VSTD::addressof(__os)), __delim(__d), __first(true) {} 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric template<typename _Tp> 870b57cec5SDimitry Andric ostream_joiner& operator=(const _Tp& __v) 880b57cec5SDimitry Andric { 890b57cec5SDimitry Andric if (!__first) 900b57cec5SDimitry Andric *__output_iter << __delim; 910b57cec5SDimitry Andric __first = false; 920b57cec5SDimitry Andric *__output_iter << __v; 930b57cec5SDimitry Andric return *this; 940b57cec5SDimitry Andric } 950b57cec5SDimitry Andric 960b57cec5SDimitry Andric ostream_joiner& operator*() _NOEXCEPT { return *this; } 970b57cec5SDimitry Andric ostream_joiner& operator++() _NOEXCEPT { return *this; } 980b57cec5SDimitry Andric ostream_joiner& operator++(int) _NOEXCEPT { return *this; } 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andricprivate: 1010b57cec5SDimitry Andric ostream_type* __output_iter; 1020b57cec5SDimitry Andric _Delim __delim; 1030b57cec5SDimitry Andric bool __first; 1040b57cec5SDimitry Andric}; 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Delim> 1080b57cec5SDimitry Andricostream_joiner<typename decay<_Delim>::type, _CharT, _Traits> 1090b57cec5SDimitry Andricmake_ostream_joiner(basic_ostream<_CharT, _Traits>& __os, _Delim && __d) 1100b57cec5SDimitry Andric{ return ostream_joiner<typename decay<_Delim>::type, _CharT, _Traits>(__os, _VSTD::forward<_Delim>(__d)); } 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_LFTS 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric#endif /* _LIBCPP_STD_VER > 11 */ 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric#endif // _LIBCPP_EXPERIMENTAL_ITERATOR 117