qxLib
generic_span.inl
Go to the documentation of this file.
1 /**
2 
3  @file generic_span.inl
4  @author Khrapov
5  @date 20.11.2022
6  @copyright © Nick Khrapov, 2022. All right reserved.
7 
8 **/
9 
10 namespace qx
11 {
12 template<class T, class traits_t>
13 constexpr generic_span<T, traits_t>::iterator::iterator(generator_type generator, size_type nIndex) noexcept
14  : m_Generator(std::move(generator))
15  , m_nIndex(nIndex)
16 {
17 }
18 
19 template<class T, class traits_t>
20 constexpr typename generic_span<T, traits_t>::iterator::reference generic_span<T, traits_t>::iterator::operator*()
21  const noexcept
22 {
23  auto generator = m_Generator;
24  return *generator();
25 }
26 
27 template<class T, class traits_t>
28 constexpr typename generic_span<T, traits_t>::iterator::pointer generic_span<T, traits_t>::iterator::operator->()
29  const noexcept
30 {
31  auto generator = m_Generator;
32  return generator();
33 }
34 
35 template<class T, class traits_t>
36 constexpr typename generic_span<T, traits_t>::iterator& generic_span<T, traits_t>::iterator::operator++() noexcept
37 {
38  m_Generator();
39 
40  if (operator->() != nullptr)
41  {
42  ++m_nIndex;
43  }
44  else
45  {
46  m_Generator = nullptr;
47  m_nIndex = std::numeric_limits<size_type>::max();
48  }
49 
50  return *this;
51 }
52 
53 template<class T, class traits_t>
54 constexpr typename generic_span<T, traits_t>::iterator generic_span<T, traits_t>::iterator::operator++(int) noexcept
55 {
56  iterator r(*this);
57  operator++()();
58  return r;
59 }
60 
61 template<class T, class traits_t>
62 constexpr bool generic_span<T, traits_t>::iterator::operator!=(const iterator& r) const noexcept
63 {
64  return !operator==(r);
65 }
66 
67 template<class T, class traits_t>
68 constexpr bool generic_span<T, traits_t>::iterator::operator==(const iterator& r) const noexcept
69 {
70  return m_nIndex == r.m_nIndex;
71 }
72 
73 template<class T, class traits_t>
74 constexpr generic_span<T, traits_t>::iterator::operator void*() const noexcept
75 {
76  auto generator = m_Generator;
77  return generator();
78 }
79 
80 template<class T, class traits_t>
81 template<class container_t>
82 inline generic_span<T, traits_t>::generic_span(container_t& container) noexcept
83  : m_InitialGenerator(
84  container.begin() != container.end()
85  ? [it = container.begin(), &container]() mutable
86  {
87  T* pRet = nullptr;
88 
89  if (it != container.end())
90  {
91  pRet = it.operator->();
92  ++it;
93  }
94 
95  return pRet;
96  }
97  : generator_type(nullptr))
98 {
99 }
100 
101 template<class T, class traits_t>
102 template<class container_t>
104  container_t& container,
105  function_type<reference(qualified_type<container_value<container_t>>&)> valueAdapter) noexcept
106  : m_InitialGenerator(create_initial_generator(container, std::move(valueAdapter)))
107 {
108 }
109 
110 template<class T, class traits_t>
111 template<class container_t>
112 inline generic_span<T, traits_t>& generic_span<T, traits_t>::operator=(container_t& container) noexcept
113 {
114  *this = generic_span(container);
115  return *this;
116 }
117 
118 template<class T, class traits_t>
119 inline bool generic_span<T, traits_t>::empty() const noexcept
120 {
121  return !static_cast<bool>(m_InitialGenerator);
122 }
123 
124 template<class T, class traits_t>
126 {
127  return m_InitialGenerator ? iterator(m_InitialGenerator, 0) : end();
128 }
129 
130 template<class T, class traits_t>
132 {
133  return iterator(nullptr, std::numeric_limits<typename iterator::size_type>::max());
134 }
135 
136 template<class T, class traits_t>
138 {
139  return begin();
140 }
141 
142 template<class T, class traits_t>
144 {
145  return end();
146 }
147 
148 template<class T, class traits_t>
149 template<class container_t, class adapter_t>
150 inline typename generic_span<T, traits_t>::generator_type generic_span<T, traits_t>::create_initial_generator(
151  container_t&& container,
152  adapter_t adapter) noexcept
153 {
154  return container.begin() != container.end()
155  ? [it = container.begin(), _adapter = std::move(adapter), &container]() mutable
156  {
157  T* pRet = nullptr;
158 
159  if (it != container.end())
160  {
161  pRet = &_adapter(*it);
162  ++it;
163  }
164 
165  return pRet;
166  }
167  : generator_type(nullptr);
168 }
169 
170 } // namespace qx
Same as std::span, but may be used with containers with forward iterators.
Definition: generic_span.h:41
generic_span & operator=(container_t &container) noexcept
operator=
iterator cend() const noexcept
Return const iterator to end.
iterator end() const noexcept
Return iterator to end.
iterator begin() const noexcept
Return iterator to beginning.
bool empty() const noexcept
Check if span is empty.
iterator cbegin() const noexcept
Return const iterator to beginning.