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 55fe6060f1SDimitry Andric#include <__memory/addressof.h> 56bdd1243dSDimitry Andric#include <__type_traits/decay.h> 57fe6060f1SDimitry Andric#include <__utility/forward.h> 5804eeddc0SDimitry Andric#include <__utility/move.h> 590eae32dcSDimitry Andric#include <experimental/__config> 600b57cec5SDimitry Andric#include <iterator> 610b57cec5SDimitry Andric 620eae32dcSDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 630eae32dcSDimitry Andric# pragma GCC system_header 640eae32dcSDimitry Andric#endif 650eae32dcSDimitry Andric 66*b3edf446SDimitry Andric_LIBCPP_PUSH_MACROS 67*b3edf446SDimitry Andric#include <__undef_macros> 68*b3edf446SDimitry Andric 6906c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14 700eae32dcSDimitry Andric 710b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_LFTS 720b57cec5SDimitry Andric 730b57cec5SDimitry Andrictemplate <class _Delim, class _CharT = char, class _Traits = char_traits<_CharT>> 740b57cec5SDimitry Andricclass ostream_joiner { 750b57cec5SDimitry Andricpublic: 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 8506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI ostream_joiner(ostream_type& __os, _Delim&& __d) 865f757f3fSDimitry Andric : __output_iter_(std::addressof(__os)), __delim_(std::move(__d)), __first_(true) {} 870b57cec5SDimitry Andric 8806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI ostream_joiner(ostream_type& __os, const _Delim& __d) 895f757f3fSDimitry Andric : __output_iter_(std::addressof(__os)), __delim_(__d), __first_(true) {} 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric template <typename _Tp> 92cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI ostream_joiner& operator=(const _Tp& __v) { 93bdd1243dSDimitry Andric if (!__first_) 94bdd1243dSDimitry Andric *__output_iter_ << __delim_; 95bdd1243dSDimitry Andric __first_ = false; 96bdd1243dSDimitry Andric *__output_iter_ << __v; 970b57cec5SDimitry Andric return *this; 980b57cec5SDimitry Andric } 990b57cec5SDimitry Andric 10006c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI ostream_joiner& operator*() _NOEXCEPT { return *this; } 10106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI ostream_joiner& operator++() _NOEXCEPT { return *this; } 10206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI ostream_joiner& operator++(int) _NOEXCEPT { return *this; } 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andricprivate: 105bdd1243dSDimitry Andric ostream_type* __output_iter_; 106bdd1243dSDimitry Andric _Delim __delim_; 107bdd1243dSDimitry Andric bool __first_; 1080b57cec5SDimitry Andric}; 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Delim> 11106c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI ostream_joiner<__decay_t<_Delim>, _CharT, _Traits> 112cb14a3feSDimitry Andricmake_ostream_joiner(basic_ostream<_CharT, _Traits>& __os, _Delim&& __d) { 113cb14a3feSDimitry Andric return ostream_joiner<__decay_t<_Delim>, _CharT, _Traits>(__os, std::forward<_Delim>(__d)); 114cb14a3feSDimitry Andric} 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_LFTS 1170b57cec5SDimitry Andric 11806c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 14 1190b57cec5SDimitry Andric 120*b3edf446SDimitry Andric_LIBCPP_POP_MACROS 121*b3edf446SDimitry Andric 122bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 1235f757f3fSDimitry Andric# include <iosfwd> 124bdd1243dSDimitry Andric# include <type_traits> 125bdd1243dSDimitry Andric#endif 126bdd1243dSDimitry Andric 1270b57cec5SDimitry Andric#endif // _LIBCPP_EXPERIMENTAL_ITERATOR 128