121c38f26SMarshall Clow// -*- C++ -*-
2eb8650a7SLouis Dionne//===----------------------------------------------------------------------===//
321c38f26SMarshall Clow//
42946cd70SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
52946cd70SChandler Carruth// See https://llvm.org/LICENSE.txt for license information.
62946cd70SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
721c38f26SMarshall Clow//
821c38f26SMarshall Clow//===----------------------------------------------------------------------===//
921c38f26SMarshall Clow
1021c38f26SMarshall Clow#ifndef _LIBCPP_EXPERIMENTAL_ITERATOR
1121c38f26SMarshall Clow#define _LIBCPP_EXPERIMENTAL_ITERATOR
1221c38f26SMarshall Clow
1321c38f26SMarshall Clow/*
1421c38f26SMarshall Clownamespace std {
1521c38f26SMarshall Clow  namespace experimental {
1621c38f26SMarshall Clow    inline namespace fundamentals_v2 {
1721c38f26SMarshall Clow
1821c38f26SMarshall Clow    template <class DelimT, class charT = char, class traits = char_traits<charT>>
1921c38f26SMarshall Clow        class ostream_joiner {
2021c38f26SMarshall Clow        public:
2121c38f26SMarshall Clow         typedef charT                        char_type;
2221c38f26SMarshall Clow         typedef traits                       traits_type;
2321c38f26SMarshall Clow         typedef basic_ostream<charT, traits> ostream_type;
2421c38f26SMarshall Clow         typedef output_iterator_tag          iterator_category;
2521c38f26SMarshall Clow         typedef void                         value_type;
2621c38f26SMarshall Clow         typedef void                         difference_type;
2721c38f26SMarshall Clow         typedef void                         pointer;
2821c38f26SMarshall Clow         typedef void                         reference;
2921c38f26SMarshall Clow
3021c38f26SMarshall Clow         ostream_joiner(ostream_type& s, const DelimT& delimiter);
3121c38f26SMarshall Clow         ostream_joiner(ostream_type& s, DelimT&& delimiter);
3221c38f26SMarshall Clow
3321c38f26SMarshall Clow         template<typename T>
3421c38f26SMarshall Clow         ostream_joiner& operator=(const T& value);
3521c38f26SMarshall Clow
3621c38f26SMarshall Clow         ostream_joiner& operator*() noexcept;
3721c38f26SMarshall Clow         ostream_joiner& operator++() noexcept;
3821c38f26SMarshall Clow         ostream_joiner& operator++(int) noexcept;
3921c38f26SMarshall Clow   private:
4021c38f26SMarshall Clow      ostream_type* out_stream;   // exposition only
4121c38f26SMarshall Clow      DelimT delim;               // exposition only
4221c38f26SMarshall Clow      bool first_element;         // exposition only
4321c38f26SMarshall Clow   };
4421c38f26SMarshall Clow
4521c38f26SMarshall Clow  template <class charT, class traits, class DelimT>
4621c38f26SMarshall Clow    ostream_joiner<decay_t<DelimT>, charT, traits>
4721c38f26SMarshall Clow    make_ostream_joiner(basic_ostream<charT, traits>& os, DelimT&& delimiter);
4821c38f26SMarshall Clow
4921c38f26SMarshall Clow    } // inline namespace fundamentals_v2
5021c38f26SMarshall Clow  } // namespace experimental
5121c38f26SMarshall Clow} // namespace std
5221c38f26SMarshall Clow
5321c38f26SMarshall Clow*/
5421c38f26SMarshall Clow
55385cc25aSLouis Dionne#include <__assert> // all public C++ headers provide the assertion handler
566adbc83eSChristopher Di Bella#include <__memory/addressof.h>
576adbc83eSChristopher Di Bella#include <__utility/forward.h>
584d81a46fSArthur O'Dwyer#include <__utility/move.h>
59413c3c4fSArthur O'Dwyer#include <experimental/__config>
60*e70533aeSLouis Dionne#include <iosfwd> // char_traits
6121c38f26SMarshall Clow#include <iterator>
6221c38f26SMarshall Clow
63413c3c4fSArthur O'Dwyer#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
64413c3c4fSArthur O'Dwyer#  pragma GCC system_header
65413c3c4fSArthur O'Dwyer#endif
66413c3c4fSArthur O'Dwyer
67413c3c4fSArthur O'Dwyer#if _LIBCPP_STD_VER > 11
68413c3c4fSArthur O'Dwyer
6921c38f26SMarshall Clow_LIBCPP_BEGIN_NAMESPACE_LFTS
7021c38f26SMarshall Clow
7121c38f26SMarshall Clowtemplate <class _Delim, class _CharT = char, class _Traits = char_traits<_CharT>>
7221c38f26SMarshall Clowclass ostream_joiner {
7321c38f26SMarshall Clowpublic:
7421c38f26SMarshall Clow
7521c38f26SMarshall Clow    typedef _CharT                               char_type;
7621c38f26SMarshall Clow    typedef _Traits                              traits_type;
7721c38f26SMarshall Clow    typedef basic_ostream<char_type,traits_type> ostream_type;
7821c38f26SMarshall Clow    typedef output_iterator_tag                  iterator_category;
7921c38f26SMarshall Clow    typedef void                                 value_type;
8021c38f26SMarshall Clow    typedef void                                 difference_type;
8121c38f26SMarshall Clow    typedef void                                 pointer;
8221c38f26SMarshall Clow    typedef void                                 reference;
8321c38f26SMarshall Clow
8421c38f26SMarshall Clow    ostream_joiner(ostream_type& __os, _Delim&& __d)
8542bfedd9SAlexander Richardson        : __output_iter(_VSTD::addressof(__os)), __delim(_VSTD::move(__d)), __first(true) {}
8621c38f26SMarshall Clow
8721c38f26SMarshall Clow    ostream_joiner(ostream_type& __os, const _Delim& __d)
8842bfedd9SAlexander Richardson        : __output_iter(_VSTD::addressof(__os)), __delim(__d), __first(true) {}
8921c38f26SMarshall Clow
9021c38f26SMarshall Clow
9121c38f26SMarshall Clow    template<typename _Tp>
9221c38f26SMarshall Clow    ostream_joiner& operator=(const _Tp& __v)
9321c38f26SMarshall Clow    {
9421c38f26SMarshall Clow        if (!__first)
9542bfedd9SAlexander Richardson            *__output_iter << __delim;
9621c38f26SMarshall Clow        __first = false;
9742bfedd9SAlexander Richardson        *__output_iter << __v;
9821c38f26SMarshall Clow        return *this;
9921c38f26SMarshall Clow    }
10021c38f26SMarshall Clow
10121c38f26SMarshall Clow    ostream_joiner& operator*()     _NOEXCEPT { return *this; }
10221c38f26SMarshall Clow    ostream_joiner& operator++()    _NOEXCEPT { return *this; }
10321c38f26SMarshall Clow    ostream_joiner& operator++(int) _NOEXCEPT { return *this; }
10421c38f26SMarshall Clow
10521c38f26SMarshall Clowprivate:
10642bfedd9SAlexander Richardson    ostream_type*   __output_iter;
10721c38f26SMarshall Clow    _Delim          __delim;
10821c38f26SMarshall Clow    bool            __first;
10921c38f26SMarshall Clow};
11021c38f26SMarshall Clow
11121c38f26SMarshall Clow
11221c38f26SMarshall Clowtemplate <class _CharT, class _Traits, class _Delim>
11321c38f26SMarshall Clowostream_joiner<typename decay<_Delim>::type, _CharT, _Traits>
11421c38f26SMarshall Clowmake_ostream_joiner(basic_ostream<_CharT, _Traits>& __os, _Delim && __d)
11521c38f26SMarshall Clow{ return ostream_joiner<typename decay<_Delim>::type, _CharT, _Traits>(__os, _VSTD::forward<_Delim>(__d)); }
11621c38f26SMarshall Clow
11721c38f26SMarshall Clow_LIBCPP_END_NAMESPACE_LFTS
11821c38f26SMarshall Clow
119413c3c4fSArthur O'Dwyer#endif // _LIBCPP_STD_VER > 11
12021c38f26SMarshall Clow
12121c38f26SMarshall Clow#endif // _LIBCPP_EXPERIMENTAL_ITERATOR
122