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 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 typename generic_span<T, traits_t>::iterator::reference generic_span<T, traits_t>::iterator::operator*() const noexcept
21 {
22  auto generator = m_Generator;
23  return *generator();
24 }
25 
26 template<class T, class traits_t>
27 typename generic_span<T, traits_t>::iterator::pointer generic_span<T, traits_t>::iterator::operator->() const noexcept
28 {
29  auto generator = m_Generator;
30  return generator();
31 }
32 
33 template<class T, class traits_t>
34 typename generic_span<T, traits_t>::iterator& generic_span<T, traits_t>::iterator::operator++() noexcept
35 {
36  m_Generator();
37 
38  if (operator->() != nullptr)
39  {
40  ++m_nIndex;
41  }
42  else
43  {
44  m_Generator = nullptr;
45  m_nIndex = std::numeric_limits<size_type>::max();
46  }
47 
48  return *this;
49 }
50 
51 template<class T, class traits_t>
52 typename generic_span<T, traits_t>::iterator generic_span<T, traits_t>::iterator::operator++(int) noexcept
53 {
54  iterator r(*this);
55  operator++();
56  return r;
57 }
58 
59 template<class T, class traits_t>
60 bool generic_span<T, traits_t>::iterator::operator!=(const iterator& r) const noexcept
61 {
62  return !operator==(r);
63 }
64 
65 template<class T, class traits_t>
66 bool generic_span<T, traits_t>::iterator::operator==(const iterator& r) const noexcept
67 {
68  return m_nIndex == r.m_nIndex;
69 }
70 
71 template<class T, class traits_t>
72 generic_span<T, traits_t>::iterator::operator void*() const noexcept
73 {
74  auto generator = m_Generator;
75  return generator();
76 }
77 
78 template<class T, class traits_t>
79 generic_span<T, traits_t>::iterator::operator bool() const noexcept
80 {
81  return m_Generator && m_nIndex != std::numeric_limits<size_type>::max();
82 }
83 
84 template<class T, class traits_t>
85 template<class container_t>
86 inline generic_span<T, traits_t>::generic_span(container_t& container) noexcept
87  : m_InitialGenerator(
88  container.begin() != container.end()
89  ? [it = container.begin(), &container]() mutable
90  {
91  T* pRet = nullptr;
92 
93  if (it != container.end())
94  {
95  pRet = it.operator->();
96  ++it;
97  }
98 
99  return pRet;
100  }
101  : generator_type(nullptr))
102 {
103 }
104 
105 template<class T, class traits_t>
106 template<class container_t>
108  container_t& container,
109  function_type<reference(qualified_type<container_value<container_t>>&)> valueAdapter) noexcept
110  : m_InitialGenerator(create_initial_generator(container, std::move(valueAdapter)))
111 {
112 }
113 
114 template<class T, class traits_t>
115 template<class container_t>
116 inline generic_span<T, traits_t>& generic_span<T, traits_t>::operator=(container_t& container) noexcept
117 {
118  *this = generic_span(container);
119  return *this;
120 }
121 
122 template<class T, class traits_t>
123 inline bool generic_span<T, traits_t>::empty() const noexcept
124 {
125  return !static_cast<bool>(m_InitialGenerator);
126 }
127 
128 template<class T, class traits_t>
130 {
131  return m_InitialGenerator ? iterator(m_InitialGenerator, 0) : end();
132 }
133 
134 template<class T, class traits_t>
136 {
137  return iterator(nullptr, std::numeric_limits<typename iterator::size_type>::max());
138 }
139 
140 template<class T, class traits_t>
142 {
143  return begin();
144 }
145 
146 template<class T, class traits_t>
148 {
149  return end();
150 }
151 
152 template<class T, class traits_t>
153 template<class container_t, class adapter_t>
154 inline typename generic_span<T, traits_t>::generator_type generic_span<T, traits_t>::create_initial_generator(
155  container_t&& container,
156  adapter_t adapter) noexcept
157 {
158  return container.begin() != container.end()
159  ? [it = container.begin(), _adapter = std::move(adapter), &container]() mutable
160  {
161  T* pRet = nullptr;
162 
163  if (it != container.end())
164  {
165  pRet = &_adapter(*it);
166  ++it;
167  }
168 
169  return pRet;
170  }
171  : generator_type(nullptr);
172 }
173 
174 } // namespace qx
Same as std::span, but may be used with any container with forward iterators.
Definition: generic_span.h:42
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.