1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_INSERT_ITERATOR_H
11#define _LIBCPP___ITERATOR_INSERT_ITERATOR_H
12
13#include <__config>
14#include <__iterator/iterator.h>
15#include <__iterator/iterator_traits.h>
16#include <__memory/addressof.h>
17#include <__ranges/access.h>
18#include <__utility/move.h>
19#include <cstddef>
20
21#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22#  pragma GCC system_header
23#endif
24
25_LIBCPP_PUSH_MACROS
26#include <__undef_macros>
27
28_LIBCPP_BEGIN_NAMESPACE_STD
29
30#if _LIBCPP_STD_VER >= 20
31template <class _Container>
32using __insert_iterator_iter_t = ranges::iterator_t<_Container>;
33#else
34template <class _Container>
35using __insert_iterator_iter_t = typename _Container::iterator;
36#endif
37
38_LIBCPP_SUPPRESS_DEPRECATED_PUSH
39template <class _Container>
40class _LIBCPP_TEMPLATE_VIS insert_iterator
41#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
42    : public iterator<output_iterator_tag, void, void, void, void>
43#endif
44{
45  _LIBCPP_SUPPRESS_DEPRECATED_POP
46
47protected:
48  _Container* container;
49  __insert_iterator_iter_t<_Container> iter;
50
51public:
52  typedef output_iterator_tag iterator_category;
53  typedef void value_type;
54#if _LIBCPP_STD_VER >= 20
55  typedef ptrdiff_t difference_type;
56#else
57  typedef void difference_type;
58#endif
59  typedef void pointer;
60  typedef void reference;
61  typedef _Container container_type;
62
63  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
64  insert_iterator(_Container& __x, __insert_iterator_iter_t<_Container> __i)
65      : container(std::addressof(__x)), iter(__i) {}
66  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator&
67  operator=(const typename _Container::value_type& __value) {
68    iter = container->insert(iter, __value);
69    ++iter;
70    return *this;
71  }
72#ifndef _LIBCPP_CXX03_LANG
73  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator&
74  operator=(typename _Container::value_type&& __value) {
75    iter = container->insert(iter, std::move(__value));
76    ++iter;
77    return *this;
78  }
79#endif // _LIBCPP_CXX03_LANG
80  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator*() { return *this; }
81  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator++() { return *this; }
82  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator++(int) { return *this; }
83};
84
85template <class _Container>
86inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator<_Container>
87inserter(_Container& __x, __insert_iterator_iter_t<_Container> __i) {
88  return insert_iterator<_Container>(__x, __i);
89}
90
91_LIBCPP_END_NAMESPACE_STD
92
93_LIBCPP_POP_MACROS
94
95#endif // _LIBCPP___ITERATOR_INSERT_ITERATOR_H
96