xref: /freebsd/contrib/llvm-project/libcxx/include/experimental/iterator (revision cb14a3fe5122c879eae1fb480ed7ce82a699ddb6)
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  typedef _CharT char_type;
750b57cec5SDimitry Andric  typedef _Traits traits_type;
760b57cec5SDimitry Andric  typedef basic_ostream<char_type, traits_type> ostream_type;
770b57cec5SDimitry Andric  typedef output_iterator_tag iterator_category;
780b57cec5SDimitry Andric  typedef void value_type;
790b57cec5SDimitry Andric  typedef void difference_type;
800b57cec5SDimitry Andric  typedef void pointer;
810b57cec5SDimitry Andric  typedef void reference;
820b57cec5SDimitry Andric
8306c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ostream_joiner(ostream_type& __os, _Delim&& __d)
845f757f3fSDimitry Andric      : __output_iter_(std::addressof(__os)), __delim_(std::move(__d)), __first_(true) {}
850b57cec5SDimitry Andric
8606c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ostream_joiner(ostream_type& __os, const _Delim& __d)
875f757f3fSDimitry Andric      : __output_iter_(std::addressof(__os)), __delim_(__d), __first_(true) {}
880b57cec5SDimitry Andric
890b57cec5SDimitry Andric  template <typename _Tp>
90*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI ostream_joiner& operator=(const _Tp& __v) {
91bdd1243dSDimitry Andric    if (!__first_)
92bdd1243dSDimitry Andric      *__output_iter_ << __delim_;
93bdd1243dSDimitry Andric    __first_ = false;
94bdd1243dSDimitry Andric    *__output_iter_ << __v;
950b57cec5SDimitry Andric    return *this;
960b57cec5SDimitry Andric  }
970b57cec5SDimitry Andric
9806c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ostream_joiner& operator*() _NOEXCEPT { return *this; }
9906c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ostream_joiner& operator++() _NOEXCEPT { return *this; }
10006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ostream_joiner& operator++(int) _NOEXCEPT { return *this; }
1010b57cec5SDimitry Andric
1020b57cec5SDimitry Andricprivate:
103bdd1243dSDimitry Andric  ostream_type* __output_iter_;
104bdd1243dSDimitry Andric  _Delim __delim_;
105bdd1243dSDimitry Andric  bool __first_;
1060b57cec5SDimitry Andric};
1070b57cec5SDimitry Andric
1080b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Delim>
10906c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI ostream_joiner<__decay_t<_Delim>, _CharT, _Traits>
110*cb14a3feSDimitry Andricmake_ostream_joiner(basic_ostream<_CharT, _Traits>& __os, _Delim&& __d) {
111*cb14a3feSDimitry Andric  return ostream_joiner<__decay_t<_Delim>, _CharT, _Traits>(__os, std::forward<_Delim>(__d));
112*cb14a3feSDimitry Andric}
1130b57cec5SDimitry Andric
1140b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_LFTS
1150b57cec5SDimitry Andric
11606c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 14
1170b57cec5SDimitry Andric
118bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
1195f757f3fSDimitry Andric#  include <iosfwd>
120bdd1243dSDimitry Andric#  include <type_traits>
121bdd1243dSDimitry Andric#endif
122bdd1243dSDimitry Andric
1230b57cec5SDimitry Andric#endif // _LIBCPP_EXPERIMENTAL_ITERATOR
124