source: mainline/uspace/lib/cpp/include/impl/array.hpp@ bfa86e5

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since bfa86e5 was bfa86e5, checked in by Dzejrou <dzejrou@…>, 7 years ago

cpp: added tuple interface for arrays

  • Property mode set to 100644
File size: 5.9 KB
Line 
1/*
2 * Copyright (c) 2017 Jaroslav Jindrak
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef LIBCPP_ARRAY
30#define LIBCPP_ARRAY
31
32#include <iterator>
33#include <utility>
34
35namespace std
36{
37 /**
38 * 23.3.2, class template array:
39 */
40
41 template<class T, size_t N>
42 struct array
43 {
44 using value_type = T;
45 using reference = T&;
46 using const_reference = const T&;
47 using size_type = size_t;
48 using difference_type = ptrdiff_t;
49 using pointer = T*;
50 using const_pointer = const T*;
51 using iterator = pointer;
52 using const_iterator = const_pointer;
53 using reverse_iterator = std::reverse_iterator<iterator>;
54 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
55
56 /**
57 * Note: In the case of N == 0 the standard mandates that
58 * begin() == end() which is achieved by setting the size
59 * to 1. Return value of data() is unspecified and front()
60 * and back() cause undefined behavior.
61 */
62 value_type elems[N ? N : 1];
63
64 void fill(const T& x)
65 {
66 fill_n(begin(), N, x);
67 }
68
69 void swap(array& other)
70 // TODO: Does not find declval atm :/
71 /* noexcept(noexcept(swap(declval<T&>(), declval<T&>()))) */
72 {
73 swap_ranges(begin(), end(), other.begin());
74 }
75
76 iterator begin() noexcept
77 {
78 return &elems[0];
79 }
80
81 iterator end() noexcept
82 {
83 return &elems[0] + N;
84 }
85
86 reverse_iterator rbegin() noexcept
87 {
88 return make_reverse_iterator(end());
89 }
90
91 reverse_iterator rend() noexcept
92 {
93 return make_reverse_iterator(begin());
94 }
95
96 const_iterator cbegin() const noexcept
97 {
98 return &elems[0];
99 }
100
101 const_iterator cend() const noexcept
102 {
103 return &elems[0] + N;
104 }
105
106 const_reverse_iterator crbegin() const noexcept
107 {
108 return make_reverse_iterator(end());
109 }
110
111 const_reverse_iterator crend() const noexcept
112 {
113 return make_reverse_iterator(begin());
114 }
115
116 reference operator[](size_type idx)
117 {
118 return elems[idx];
119 }
120
121 constexpr const_reference operator[](size_type idx) const
122 {
123 return elems[idx];
124 }
125
126 reference at(size_type idx)
127 {
128 // TODO: Bounds checking.
129 return elems[idx];
130 }
131
132 constexpr const_reference at(size_type idx) const
133 {
134 // TODO: Bounds checking.
135 return elems[idx];
136 }
137
138 reference front()
139 {
140 return elems[0];
141 }
142
143 constexpr const_reference front() const
144 {
145 return elems[0];
146 }
147
148 reference back()
149 {
150 return elems[N - 1];
151 }
152
153 constexpr const_reference back() const
154 {
155 return elems[N - 1];
156 }
157
158 pointer data() noexcept
159 {
160 return &elems[0];
161 }
162
163 const_pointer data() const noexcept
164 {
165 return &elems[0];
166 }
167
168 size_type size() const noexcept
169 {
170 return N;
171 }
172 };
173
174 template<class T, size_t N>
175 void swap(array<T, N>& lhs, array<T, N>& rhs) noexcept(noexcept(lhs.swap(rhs)))
176 {
177 lhs.swap(rhs);
178 }
179
180 // TODO: tuple interface for array 23.3.2.9
181 /**
182 * 23.3.2.9, tuple interface for class template array:
183 */
184
185 template<class>
186 struct tuple_size;
187
188 template<class T, size_t N>
189 struct tuple_size<array<T, N>>
190 : integral_constant<size_t, N>
191 { /* DUMMY BODY */ };
192
193 template<size_t, class>
194 struct tuple_element;
195
196 template<size_t I, class T, size_t N>
197 struct tuple_element<I, array<T, N>>
198 : aux::type_is<T>
199 { /* DUMMY BODY */ };
200
201 template<size_t I, class T, size_t N>
202 constexpr T& get(array<T, N>& arr) noexcept
203 {
204 static_assert(I < N, "index out of bounds");
205
206 return arr[I];
207 }
208
209 template<size_t I, class T, size_t N>
210 constexpr T&& get(array<T, N>&& arr) noexcept
211 {
212 return move(get<I>(arr));
213 }
214
215 template<size_t I, class T, size_t N>
216 constexpr const T& get(const array<T, N>& arr) noexcept
217 {
218 static_assert(I < N, "index out of bounds");
219
220 return arr[I];
221 }
222}
223
224#endif
Note: See TracBrowser for help on using the repository browser.