Skip to content

Commit 8802b06

Browse files
committed
adaptor for C raw array
1 parent 427c55e commit 8802b06

File tree

1 file changed

+293
-0
lines changed

1 file changed

+293
-0
lines changed
Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
/***************************************************************************
2+
* Copyright (c) 2016, Johan Mabille and Sylvain Corlay *
3+
* *
4+
* Distributed under the terms of the BSD 3-Clause License. *
5+
* *
6+
* The full license is in the file LICENSE, distributed with this software. *
7+
****************************************************************************/
8+
9+
#ifndef XPOINTER_ADAPTOR_HPP
10+
#define XPOINTER_ADAPTOR_HPP
11+
12+
#include <iterator>
13+
#include <algorithm>
14+
#include <memory>
15+
16+
namespace xt
17+
{
18+
19+
template <class T, class A = std::allocator<T>>
20+
class xpointer_adaptor
21+
{
22+
23+
public:
24+
25+
using allocator_type = A;
26+
using value_type = typename allocator_type::value_type;
27+
using reference = typename allocator_type::reference;
28+
using const_reference = typename allocator_type::const_reference;
29+
using pointer = typename allocator_type::pointer;
30+
using const_pointer = typename allocator_type::const_pointer;
31+
using size_type = typename allocator_type::size_type;
32+
using difference_type = typename allocator_type::difference_type;
33+
34+
using iterator = pointer;
35+
using const_iterator = const_pointer;
36+
using reverse_iterator = std::reverse_iterator<iterator>;
37+
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
38+
39+
xpointer_adaptor(pointer& data, size_type size,
40+
const allocator_type& alloc = allocator_type());
41+
~xpointer_adaptor() = default;
42+
43+
xpointer_adaptor(const xpointer_adaptor&) = default;
44+
xpointer_adaptor& operator=(const xpointer_adaptor&);
45+
46+
xpointer_adaptor(xpointer_adaptor&&) = default;
47+
xpointer_adaptor& operator=(xpointer_adaptor&&);
48+
49+
bool empty() const noexcept;
50+
size_type size() const noexcept;
51+
52+
void resize(size_type count);
53+
void resize(size_type count, const_reference value);
54+
55+
reference operator[](size_type i);
56+
const_reference operator[](size_type i) const;
57+
58+
reference front();
59+
const_reference front() const;
60+
61+
reference back();
62+
const_reference back() const;
63+
64+
pointer data() noexcept;
65+
const_pointer data() const noexcept;
66+
67+
iterator begin() noexcept;
68+
iterator end() noexcept;
69+
70+
const_iterator begin() const noexcept;
71+
const_iterator end() const noexcept;
72+
73+
const_iterator cbegin() const noexcept;
74+
const_iterator cend() const noexcept;
75+
76+
reverse_iterator rbegin() noexcept;
77+
reverse_iterator rend() noexcept;
78+
79+
const_reverse_iterator rbegin() const noexcept;
80+
const_reverse_iterator rend() const noexcept;
81+
82+
const_reverse_iterator crbegin() const noexcept;
83+
const_reverse_iterator crend() const noexcept;
84+
85+
private:
86+
87+
void resize_impl(size_type count);
88+
void swap_and_destroy(pointer& old_data, size_type& old_size,
89+
pointer& new_data, size_type& new_size);
90+
91+
pointer& p_data;
92+
size_type m_size;
93+
allocator_type m_allocator;
94+
};
95+
96+
template <class T, class A>
97+
inline xpointer_adaptor<T, A>::xpointer_adaptor(pointer& data, size_type size,
98+
const allocator_type& alloc)
99+
: p_data(data), m_size(size), m_allocator(alloc)
100+
{
101+
}
102+
103+
template <class T, class A>
104+
inline xpointer_adaptor<T, A>&
105+
xpointer_adaptor<T, A>::operator=(const xpointer_adaptor& rhs)
106+
{
107+
size_type new_size = rhs.size();
108+
pointer new_data = m_allocator.allocate(new_size);
109+
std::copy(rhs.begin(), rhs.end(), new_data);
110+
swap_and_destroy(p_data, m_size, new_data, new_size);
111+
return *this;
112+
}
113+
114+
template <class T, class A>
115+
inline xpointer_adaptor<T, A>&
116+
xpointer_adaptor<T, A>::operator=(xpointer_adaptor&& rhs)
117+
{
118+
std::swap(p_data, rhs.p_data);
119+
std::swap(m_size, rhs.m_size);
120+
return *this;
121+
}
122+
123+
template <class T, class A>
124+
inline bool xpointer_adaptor<T, A>::empty() const noexcept
125+
{
126+
return size() == 0;
127+
}
128+
129+
template <class T, class A>
130+
inline auto xpointer_adaptor<T, A>::size() const noexcept -> size_type
131+
{
132+
return m_size;
133+
}
134+
135+
template <class T, class A>
136+
inline void xpointer_adaptor<T, A>::resize(size_type count)
137+
{
138+
resize_impl(count);
139+
}
140+
141+
template <class T, class A>
142+
inline void xpointer_adaptor<T, A>::resize(size_type count, const_reference value)
143+
{
144+
size_type old_size = size();
145+
resize_impl(count);
146+
if (count > old_size)
147+
{
148+
std::fill(begin() + old_size, end(), value);
149+
}
150+
}
151+
152+
template <class T, class A>
153+
inline auto xpointer_adaptor<T, A>::operator[](size_type i) -> reference
154+
{
155+
return p_data[i];
156+
}
157+
158+
template <class T, class A>
159+
inline auto xpointer_adaptor<T, A>::operator[](size_type i) const -> const_reference
160+
{
161+
return p_data[i];
162+
}
163+
164+
template <class T, class A>
165+
inline auto xpointer_adaptor<T, A>::front() -> reference
166+
{
167+
return p_data[0];
168+
}
169+
170+
template <class T, class A>
171+
inline auto xpointer_adaptor<T, A>::front() const -> const_reference
172+
{
173+
return p_data[0];
174+
}
175+
176+
template <class T, class A>
177+
inline auto xpointer_adaptor<T, A>::back() -> reference
178+
{
179+
return p_data[size() - 1];
180+
}
181+
182+
template <class T, class A>
183+
inline auto xpointer_adaptor<T, A>::back() const -> const_reference
184+
{
185+
return p_data[size() - 1];
186+
}
187+
188+
template <class T, class A>
189+
inline auto xpointer_adaptor<T, A>::data() noexcept -> pointer
190+
{
191+
return p_data;
192+
}
193+
194+
template <class T, class A>
195+
inline auto xpointer_adaptor<T, A>::data() const noexcept -> const_pointer
196+
{
197+
return p_data;
198+
}
199+
200+
template <class T, class A>
201+
inline auto xpointer_adaptor<T, A>::begin() noexcept -> iterator
202+
{
203+
return data();
204+
}
205+
206+
template <class T, class A>
207+
inline auto xpointer_adaptor<T, A>::end() noexcept-> iterator
208+
{
209+
return data() + size();
210+
}
211+
212+
template <class T, class A>
213+
inline auto xpointer_adaptor<T, A>::begin() const noexcept -> const_iterator
214+
{
215+
return data();
216+
}
217+
218+
template <class T, class A>
219+
inline auto xpointer_adaptor<T, A>::end() const noexcept -> const_iterator
220+
{
221+
return data() + size();
222+
}
223+
224+
template <class T, class A>
225+
inline auto xpointer_adaptor<T, A>::cbegin() const noexcept -> const_iterator
226+
{
227+
return begin();
228+
}
229+
230+
template <class T, class A>
231+
inline auto xpointer_adaptor<T, A>::cend() const noexcept -> const_iterator
232+
{
233+
return end();
234+
}
235+
236+
template <class T, class A>
237+
inline auto xpointer_adaptor<T, A>::rbegin() noexcept -> reverse_iterator
238+
{
239+
return reverse_iterator(end());
240+
}
241+
242+
template <class T, class A>
243+
inline auto xpointer_adaptor<T, A>::rend() noexcept -> reverse_iterator
244+
{
245+
return reverse_iterator(begin());
246+
}
247+
248+
template <class T, class A>
249+
inline auto xpointer_adaptor<T, A>::rbegin() const noexcept -> const_reverse_iterator
250+
{
251+
return const_reverse_iterator(end());
252+
}
253+
254+
template <class T, class A>
255+
inline auto xpointer_adaptor<T, A>::rend() const noexcept -> const_reverse_iterator
256+
{
257+
return const_reverse_iterator(begin());
258+
}
259+
260+
template <class T, class A>
261+
inline auto xpointer_adaptor<T, A>::crbegin() const noexcept -> const_reverse_iterator
262+
{
263+
return rbegin()
264+
}
265+
266+
template <class T, class A>
267+
inline auto xpointer_adaptor<T, A>::crend() const noexcept -> const_reverse_iterator
268+
{
269+
return rend();
270+
}
271+
272+
template <class T, class A>
273+
inline void xpointer_adaptor<T, A>::resize_impl(size_type count)
274+
{
275+
pointer new_data = m_allocator.allocate(count);
276+
size_type end = std::min(size(), count);
277+
std::move(begin(), begin() + end, new_data);
278+
swap_and_destroy(p_data, m_size, new_data, count);
279+
}
280+
281+
template <class T, class A>
282+
inline void xpointer_adaptor<T, A>::swap_and_destroy(pointer& old_data, size_type& old_size,
283+
pointer& new_data, size_type& new_size)
284+
{
285+
std::swap(old_data, new_data);
286+
std::swap(old_size, new_size);
287+
std::for_each(new_data, new_data + new_size,
288+
[this](T& value) { m_allocator.destroy(&value); });
289+
m_allocator.deallocate(new_data, new_size);
290+
}
291+
}
292+
293+
#endif

0 commit comments

Comments
 (0)