10b57cec5SDimitry Andric// -*- C++ -*- 2349cc55cSDimitry 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 5581ad6265SDimitry Andric#include <__assert> // all public C++ headers provide the assertion handler 56fe6060f1SDimitry Andric#include <__memory/addressof.h> 57*bdd1243dSDimitry Andric#include <__type_traits/decay.h> 58fe6060f1SDimitry Andric#include <__utility/forward.h> 5904eeddc0SDimitry Andric#include <__utility/move.h> 600eae32dcSDimitry Andric#include <experimental/__config> 6181ad6265SDimitry Andric#include <iosfwd> // char_traits 620b57cec5SDimitry Andric#include <iterator> 630b57cec5SDimitry Andric 640eae32dcSDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 650eae32dcSDimitry Andric# pragma GCC system_header 660eae32dcSDimitry Andric#endif 670eae32dcSDimitry Andric 680eae32dcSDimitry Andric#if _LIBCPP_STD_VER > 11 690eae32dcSDimitry Andric 700b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_LFTS 710b57cec5SDimitry Andric 720b57cec5SDimitry Andrictemplate <class _Delim, class _CharT = char, class _Traits = char_traits<_CharT>> 730b57cec5SDimitry Andricclass ostream_joiner { 740b57cec5SDimitry Andricpublic: 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric typedef _CharT char_type; 770b57cec5SDimitry Andric typedef _Traits traits_type; 780b57cec5SDimitry Andric typedef basic_ostream<char_type,traits_type> ostream_type; 790b57cec5SDimitry Andric typedef output_iterator_tag iterator_category; 800b57cec5SDimitry Andric typedef void value_type; 810b57cec5SDimitry Andric typedef void difference_type; 820b57cec5SDimitry Andric typedef void pointer; 830b57cec5SDimitry Andric typedef void reference; 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric ostream_joiner(ostream_type& __os, _Delim&& __d) 86*bdd1243dSDimitry Andric : __output_iter_(_VSTD::addressof(__os)), __delim_(_VSTD::move(__d)), __first_(true) {} 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric ostream_joiner(ostream_type& __os, const _Delim& __d) 89*bdd1243dSDimitry Andric : __output_iter_(_VSTD::addressof(__os)), __delim_(__d), __first_(true) {} 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric 920b57cec5SDimitry Andric template<typename _Tp> 930b57cec5SDimitry Andric ostream_joiner& operator=(const _Tp& __v) 940b57cec5SDimitry Andric { 95*bdd1243dSDimitry Andric if (!__first_) 96*bdd1243dSDimitry Andric *__output_iter_ << __delim_; 97*bdd1243dSDimitry Andric __first_ = false; 98*bdd1243dSDimitry Andric *__output_iter_ << __v; 990b57cec5SDimitry Andric return *this; 1000b57cec5SDimitry Andric } 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric ostream_joiner& operator*() _NOEXCEPT { return *this; } 1030b57cec5SDimitry Andric ostream_joiner& operator++() _NOEXCEPT { return *this; } 1040b57cec5SDimitry Andric ostream_joiner& operator++(int) _NOEXCEPT { return *this; } 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andricprivate: 107*bdd1243dSDimitry Andric ostream_type* __output_iter_; 108*bdd1243dSDimitry Andric _Delim __delim_; 109*bdd1243dSDimitry Andric bool __first_; 1100b57cec5SDimitry Andric}; 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Delim> 114*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI ostream_joiner<typename decay<_Delim>::type, _CharT, _Traits> 1150b57cec5SDimitry Andricmake_ostream_joiner(basic_ostream<_CharT, _Traits>& __os, _Delim && __d) 1160b57cec5SDimitry Andric{ return ostream_joiner<typename decay<_Delim>::type, _CharT, _Traits>(__os, _VSTD::forward<_Delim>(__d)); } 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_LFTS 1190b57cec5SDimitry Andric 1200eae32dcSDimitry Andric#endif // _LIBCPP_STD_VER > 11 1210b57cec5SDimitry Andric 122*bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 123*bdd1243dSDimitry Andric# include <type_traits> 124*bdd1243dSDimitry Andric#endif 125*bdd1243dSDimitry Andric 1260b57cec5SDimitry Andric#endif // _LIBCPP_EXPERIMENTAL_ITERATOR 127