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> 56fe6060f1SDimitry Andric#include <__utility/forward.h> 57*04eeddc0SDimitry Andric#include <__utility/move.h> 580eae32dcSDimitry Andric#include <experimental/__config> 590b57cec5SDimitry Andric#include <iterator> 600b57cec5SDimitry Andric 610eae32dcSDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 620eae32dcSDimitry Andric#pragma GCC system_header 630eae32dcSDimitry Andric#endif 640eae32dcSDimitry Andric 650eae32dcSDimitry Andric#if _LIBCPP_STD_VER > 11 660eae32dcSDimitry Andric 670b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_LFTS 680b57cec5SDimitry Andric 690b57cec5SDimitry Andrictemplate <class _Delim, class _CharT = char, class _Traits = char_traits<_CharT>> 700b57cec5SDimitry Andricclass ostream_joiner { 710b57cec5SDimitry Andricpublic: 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric typedef _CharT char_type; 740b57cec5SDimitry Andric typedef _Traits traits_type; 750b57cec5SDimitry Andric typedef basic_ostream<char_type,traits_type> ostream_type; 760b57cec5SDimitry Andric typedef output_iterator_tag iterator_category; 770b57cec5SDimitry Andric typedef void value_type; 780b57cec5SDimitry Andric typedef void difference_type; 790b57cec5SDimitry Andric typedef void pointer; 800b57cec5SDimitry Andric typedef void reference; 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric ostream_joiner(ostream_type& __os, _Delim&& __d) 830b57cec5SDimitry Andric : __output_iter(_VSTD::addressof(__os)), __delim(_VSTD::move(__d)), __first(true) {} 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric ostream_joiner(ostream_type& __os, const _Delim& __d) 860b57cec5SDimitry Andric : __output_iter(_VSTD::addressof(__os)), __delim(__d), __first(true) {} 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric template<typename _Tp> 900b57cec5SDimitry Andric ostream_joiner& operator=(const _Tp& __v) 910b57cec5SDimitry Andric { 920b57cec5SDimitry Andric if (!__first) 930b57cec5SDimitry Andric *__output_iter << __delim; 940b57cec5SDimitry Andric __first = false; 950b57cec5SDimitry Andric *__output_iter << __v; 960b57cec5SDimitry Andric return *this; 970b57cec5SDimitry Andric } 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric ostream_joiner& operator*() _NOEXCEPT { return *this; } 1000b57cec5SDimitry Andric ostream_joiner& operator++() _NOEXCEPT { return *this; } 1010b57cec5SDimitry Andric ostream_joiner& operator++(int) _NOEXCEPT { return *this; } 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andricprivate: 1040b57cec5SDimitry Andric ostream_type* __output_iter; 1050b57cec5SDimitry Andric _Delim __delim; 1060b57cec5SDimitry Andric bool __first; 1070b57cec5SDimitry Andric}; 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Delim> 1110b57cec5SDimitry Andricostream_joiner<typename decay<_Delim>::type, _CharT, _Traits> 1120b57cec5SDimitry Andricmake_ostream_joiner(basic_ostream<_CharT, _Traits>& __os, _Delim && __d) 1130b57cec5SDimitry Andric{ return ostream_joiner<typename decay<_Delim>::type, _CharT, _Traits>(__os, _VSTD::forward<_Delim>(__d)); } 1140b57cec5SDimitry Andric 1150b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_LFTS 1160b57cec5SDimitry Andric 1170eae32dcSDimitry Andric#endif // _LIBCPP_STD_VER > 11 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andric#endif // _LIBCPP_EXPERIMENTAL_ITERATOR 120