xref: /freebsd/contrib/llvm-project/libcxx/include/experimental/iterator (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
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