xref: /freebsd/contrib/llvm-project/libcxx/include/experimental/iterator (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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>
56bdd1243dSDimitry Andric#include <__type_traits/decay.h>
57fe6060f1SDimitry Andric#include <__utility/forward.h>
5804eeddc0SDimitry Andric#include <__utility/move.h>
590eae32dcSDimitry Andric#include <experimental/__config>
600b57cec5SDimitry Andric#include <iterator>
610b57cec5SDimitry Andric
620eae32dcSDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
630eae32dcSDimitry Andric#  pragma GCC system_header
640eae32dcSDimitry Andric#endif
650eae32dcSDimitry Andric
66*b3edf446SDimitry Andric_LIBCPP_PUSH_MACROS
67*b3edf446SDimitry Andric#include <__undef_macros>
68*b3edf446SDimitry Andric
6906c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14
700eae32dcSDimitry Andric
710b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_LFTS
720b57cec5SDimitry Andric
730b57cec5SDimitry Andrictemplate <class _Delim, class _CharT = char, class _Traits = char_traits<_CharT>>
740b57cec5SDimitry Andricclass ostream_joiner {
750b57cec5SDimitry Andricpublic:
760b57cec5SDimitry Andric  typedef _CharT char_type;
770b57cec5SDimitry Andric  typedef _Traits traits_type;
780b57cec5SDimitry Andric  typedef basic_ostream<char_type, traits_type> ostream_type;
790b57cec5SDimitry Andric  typedef output_iterator_tag iterator_category;
800b57cec5SDimitry Andric  typedef void value_type;
810b57cec5SDimitry Andric  typedef void difference_type;
820b57cec5SDimitry Andric  typedef void pointer;
830b57cec5SDimitry Andric  typedef void reference;
840b57cec5SDimitry Andric
8506c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ostream_joiner(ostream_type& __os, _Delim&& __d)
865f757f3fSDimitry Andric      : __output_iter_(std::addressof(__os)), __delim_(std::move(__d)), __first_(true) {}
870b57cec5SDimitry Andric
8806c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ostream_joiner(ostream_type& __os, const _Delim& __d)
895f757f3fSDimitry Andric      : __output_iter_(std::addressof(__os)), __delim_(__d), __first_(true) {}
900b57cec5SDimitry Andric
910b57cec5SDimitry Andric  template <typename _Tp>
92cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI ostream_joiner& operator=(const _Tp& __v) {
93bdd1243dSDimitry Andric    if (!__first_)
94bdd1243dSDimitry Andric      *__output_iter_ << __delim_;
95bdd1243dSDimitry Andric    __first_ = false;
96bdd1243dSDimitry Andric    *__output_iter_ << __v;
970b57cec5SDimitry Andric    return *this;
980b57cec5SDimitry Andric  }
990b57cec5SDimitry Andric
10006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ostream_joiner& operator*() _NOEXCEPT { return *this; }
10106c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ostream_joiner& operator++() _NOEXCEPT { return *this; }
10206c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ostream_joiner& operator++(int) _NOEXCEPT { return *this; }
1030b57cec5SDimitry Andric
1040b57cec5SDimitry Andricprivate:
105bdd1243dSDimitry Andric  ostream_type* __output_iter_;
106bdd1243dSDimitry Andric  _Delim __delim_;
107bdd1243dSDimitry Andric  bool __first_;
1080b57cec5SDimitry Andric};
1090b57cec5SDimitry Andric
1100b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Delim>
11106c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI ostream_joiner<__decay_t<_Delim>, _CharT, _Traits>
112cb14a3feSDimitry Andricmake_ostream_joiner(basic_ostream<_CharT, _Traits>& __os, _Delim&& __d) {
113cb14a3feSDimitry Andric  return ostream_joiner<__decay_t<_Delim>, _CharT, _Traits>(__os, std::forward<_Delim>(__d));
114cb14a3feSDimitry Andric}
1150b57cec5SDimitry Andric
1160b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_LFTS
1170b57cec5SDimitry Andric
11806c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 14
1190b57cec5SDimitry Andric
120*b3edf446SDimitry Andric_LIBCPP_POP_MACROS
121*b3edf446SDimitry Andric
122bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
1235f757f3fSDimitry Andric#  include <iosfwd>
124bdd1243dSDimitry Andric#  include <type_traits>
125bdd1243dSDimitry Andric#endif
126bdd1243dSDimitry Andric
1270b57cec5SDimitry Andric#endif // _LIBCPP_EXPERIMENTAL_ITERATOR
128