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> 57bdd1243dSDimitry Andric#include <__type_traits/decay.h> 58fe6060f1SDimitry Andric#include <__utility/forward.h> 5904eeddc0SDimitry Andric#include <__utility/move.h> 600eae32dcSDimitry Andric#include <experimental/__config> 610b57cec5SDimitry Andric#include <iterator> 620b57cec5SDimitry Andric 630eae32dcSDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 640eae32dcSDimitry Andric# pragma GCC system_header 650eae32dcSDimitry Andric#endif 660eae32dcSDimitry Andric 6706c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14 680eae32dcSDimitry Andric 690b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_LFTS 700b57cec5SDimitry Andric 710b57cec5SDimitry Andrictemplate <class _Delim, class _CharT = char, class _Traits = char_traits<_CharT>> 720b57cec5SDimitry Andricclass ostream_joiner { 730b57cec5SDimitry Andricpublic: 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric typedef _CharT char_type; 760b57cec5SDimitry Andric typedef _Traits traits_type; 770b57cec5SDimitry Andric typedef basic_ostream<char_type,traits_type> ostream_type; 780b57cec5SDimitry Andric typedef output_iterator_tag iterator_category; 790b57cec5SDimitry Andric typedef void value_type; 800b57cec5SDimitry Andric typedef void difference_type; 810b57cec5SDimitry Andric typedef void pointer; 820b57cec5SDimitry Andric typedef void reference; 830b57cec5SDimitry Andric 8406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI ostream_joiner(ostream_type& __os, _Delim&& __d) 85*5f757f3fSDimitry Andric : __output_iter_(std::addressof(__os)), __delim_(std::move(__d)), __first_(true) {} 860b57cec5SDimitry Andric 8706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI ostream_joiner(ostream_type& __os, const _Delim& __d) 88*5f757f3fSDimitry Andric : __output_iter_(std::addressof(__os)), __delim_(__d), __first_(true) {} 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric template<typename _Tp> 9206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI ostream_joiner& operator=(const _Tp& __v) 930b57cec5SDimitry Andric { 94bdd1243dSDimitry Andric if (!__first_) 95bdd1243dSDimitry Andric *__output_iter_ << __delim_; 96bdd1243dSDimitry Andric __first_ = false; 97bdd1243dSDimitry Andric *__output_iter_ << __v; 980b57cec5SDimitry Andric return *this; 990b57cec5SDimitry Andric } 1000b57cec5SDimitry Andric 10106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI ostream_joiner& operator*() _NOEXCEPT { return *this; } 10206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI ostream_joiner& operator++() _NOEXCEPT { return *this; } 10306c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI ostream_joiner& operator++(int) _NOEXCEPT { return *this; } 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andricprivate: 106bdd1243dSDimitry Andric ostream_type* __output_iter_; 107bdd1243dSDimitry Andric _Delim __delim_; 108bdd1243dSDimitry Andric bool __first_; 1090b57cec5SDimitry Andric}; 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Delim> 11306c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI ostream_joiner<__decay_t<_Delim>, _CharT, _Traits> 1140b57cec5SDimitry Andricmake_ostream_joiner(basic_ostream<_CharT, _Traits>& __os, _Delim && __d) 115*5f757f3fSDimitry Andric{ return ostream_joiner<__decay_t<_Delim>, _CharT, _Traits>(__os, std::forward<_Delim>(__d)); } 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_LFTS 1180b57cec5SDimitry Andric 11906c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 14 1200b57cec5SDimitry Andric 121bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 122*5f757f3fSDimitry Andric# include <iosfwd> 123bdd1243dSDimitry Andric# include <type_traits> 124bdd1243dSDimitry Andric#endif 125bdd1243dSDimitry Andric 1260b57cec5SDimitry Andric#endif // _LIBCPP_EXPERIMENTAL_ITERATOR 127