xref: /freebsd/contrib/llvm-project/libcxx/include/experimental/iterator (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
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>
57*bdd1243dSDimitry Andric#include <__type_traits/decay.h>
58fe6060f1SDimitry Andric#include <__utility/forward.h>
5904eeddc0SDimitry Andric#include <__utility/move.h>
600eae32dcSDimitry Andric#include <experimental/__config>
6181ad6265SDimitry Andric#include <iosfwd> // char_traits
620b57cec5SDimitry Andric#include <iterator>
630b57cec5SDimitry Andric
640eae32dcSDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
650eae32dcSDimitry Andric#  pragma GCC system_header
660eae32dcSDimitry Andric#endif
670eae32dcSDimitry Andric
680eae32dcSDimitry Andric#if _LIBCPP_STD_VER > 11
690eae32dcSDimitry Andric
700b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_LFTS
710b57cec5SDimitry Andric
720b57cec5SDimitry Andrictemplate <class _Delim, class _CharT = char, class _Traits = char_traits<_CharT>>
730b57cec5SDimitry Andricclass ostream_joiner {
740b57cec5SDimitry Andricpublic:
750b57cec5SDimitry Andric
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
850b57cec5SDimitry Andric    ostream_joiner(ostream_type& __os, _Delim&& __d)
86*bdd1243dSDimitry Andric        : __output_iter_(_VSTD::addressof(__os)), __delim_(_VSTD::move(__d)), __first_(true) {}
870b57cec5SDimitry Andric
880b57cec5SDimitry Andric    ostream_joiner(ostream_type& __os, const _Delim& __d)
89*bdd1243dSDimitry Andric        : __output_iter_(_VSTD::addressof(__os)), __delim_(__d), __first_(true) {}
900b57cec5SDimitry Andric
910b57cec5SDimitry Andric
920b57cec5SDimitry Andric    template<typename _Tp>
930b57cec5SDimitry Andric    ostream_joiner& operator=(const _Tp& __v)
940b57cec5SDimitry Andric    {
95*bdd1243dSDimitry Andric        if (!__first_)
96*bdd1243dSDimitry Andric            *__output_iter_ << __delim_;
97*bdd1243dSDimitry Andric        __first_ = false;
98*bdd1243dSDimitry Andric        *__output_iter_ << __v;
990b57cec5SDimitry Andric        return *this;
1000b57cec5SDimitry Andric    }
1010b57cec5SDimitry Andric
1020b57cec5SDimitry Andric    ostream_joiner& operator*()     _NOEXCEPT { return *this; }
1030b57cec5SDimitry Andric    ostream_joiner& operator++()    _NOEXCEPT { return *this; }
1040b57cec5SDimitry Andric    ostream_joiner& operator++(int) _NOEXCEPT { return *this; }
1050b57cec5SDimitry Andric
1060b57cec5SDimitry Andricprivate:
107*bdd1243dSDimitry Andric    ostream_type*   __output_iter_;
108*bdd1243dSDimitry Andric    _Delim          __delim_;
109*bdd1243dSDimitry Andric    bool            __first_;
1100b57cec5SDimitry Andric};
1110b57cec5SDimitry Andric
1120b57cec5SDimitry Andric
1130b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _Delim>
114*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI ostream_joiner<typename decay<_Delim>::type, _CharT, _Traits>
1150b57cec5SDimitry Andricmake_ostream_joiner(basic_ostream<_CharT, _Traits>& __os, _Delim && __d)
1160b57cec5SDimitry Andric{ return ostream_joiner<typename decay<_Delim>::type, _CharT, _Traits>(__os, _VSTD::forward<_Delim>(__d)); }
1170b57cec5SDimitry Andric
1180b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_LFTS
1190b57cec5SDimitry Andric
1200eae32dcSDimitry Andric#endif // _LIBCPP_STD_VER > 11
1210b57cec5SDimitry Andric
122*bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
123*bdd1243dSDimitry Andric#  include <type_traits>
124*bdd1243dSDimitry Andric#endif
125*bdd1243dSDimitry Andric
1260b57cec5SDimitry Andric#endif // _LIBCPP_EXPERIMENTAL_ITERATOR
127