1// -*- C++ -*-
2//===----------------------------- iterator -------------------------------===//
3//
4//                     The LLVM Compiler Infrastructure
5//
6// This file is distributed under the University of Illinois Open Source
7// License. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_EXPERIMENTAL_ITERATOR
12#define _LIBCPP_EXPERIMENTAL_ITERATOR
13
14/*
15namespace std {
16  namespace experimental {
17    inline namespace fundamentals_v2 {
18
19    template <class DelimT, class charT = char, class traits = char_traits<charT>>
20        class ostream_joiner {
21        public:
22         typedef charT                        char_type;
23         typedef traits                       traits_type;
24         typedef basic_ostream<charT, traits> ostream_type;
25         typedef output_iterator_tag          iterator_category;
26         typedef void                         value_type;
27         typedef void                         difference_type;
28         typedef void                         pointer;
29         typedef void                         reference;
30
31         ostream_joiner(ostream_type& s, const DelimT& delimiter);
32         ostream_joiner(ostream_type& s, DelimT&& delimiter);
33
34         template<typename T>
35         ostream_joiner& operator=(const T& value);
36
37         ostream_joiner& operator*() noexcept;
38         ostream_joiner& operator++() noexcept;
39         ostream_joiner& operator++(int) noexcept;
40   private:
41      ostream_type* out_stream;   // exposition only
42      DelimT delim;               // exposition only
43      bool first_element;         // exposition only
44   };
45
46  template <class charT, class traits, class DelimT>
47    ostream_joiner<decay_t<DelimT>, charT, traits>
48    make_ostream_joiner(basic_ostream<charT, traits>& os, DelimT&& delimiter);
49
50    } // inline namespace fundamentals_v2
51  } // namespace experimental
52} // namespace std
53
54*/
55
56#include <experimental/__config>
57
58#if _LIBCPP_STD_VER > 11
59
60#include <iterator>
61
62_LIBCPP_BEGIN_NAMESPACE_LFTS
63
64template <class _Delim, class _CharT = char, class _Traits = char_traits<_CharT>>
65class ostream_joiner {
66public:
67
68    typedef _CharT                               char_type;
69    typedef _Traits                              traits_type;
70    typedef basic_ostream<char_type,traits_type> ostream_type;
71    typedef output_iterator_tag                  iterator_category;
72    typedef void                                 value_type;
73    typedef void                                 difference_type;
74    typedef void                                 pointer;
75    typedef void                                 reference;
76
77    ostream_joiner(ostream_type& __os, _Delim&& __d)
78        : __output_iter(_VSTD::addressof(__os)), __delim(_VSTD::move(__d)), __first(true) {}
79
80    ostream_joiner(ostream_type& __os, const _Delim& __d)
81        : __output_iter(_VSTD::addressof(__os)), __delim(__d), __first(true) {}
82
83
84    template<typename _Tp>
85    ostream_joiner& operator=(const _Tp& __v)
86    {
87        if (!__first)
88            *__output_iter << __delim;
89        __first = false;
90        *__output_iter << __v;
91        return *this;
92    }
93
94    ostream_joiner& operator*()     _NOEXCEPT { return *this; }
95    ostream_joiner& operator++()    _NOEXCEPT { return *this; }
96    ostream_joiner& operator++(int) _NOEXCEPT { return *this; }
97
98private:
99    ostream_type*   __output_iter;
100    _Delim          __delim;
101    bool            __first;
102};
103
104
105template <class _CharT, class _Traits, class _Delim>
106ostream_joiner<typename decay<_Delim>::type, _CharT, _Traits>
107make_ostream_joiner(basic_ostream<_CharT, _Traits>& __os, _Delim && __d)
108{ return ostream_joiner<typename decay<_Delim>::type, _CharT, _Traits>(__os, _VSTD::forward<_Delim>(__d)); }
109
110_LIBCPP_END_NAMESPACE_LFTS
111
112#endif /* _LIBCPP_STD_VER > 11 */
113
114#endif // _LIBCPP_EXPERIMENTAL_ITERATOR
115