Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: mbed_DS28EC20_GPIO
span.hpp
00001 /******************************************************************************* 00002 * Copyright (C) 2018 Maxim Integrated Products, Inc., All Rights Reserved. 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a 00005 * copy of this software and associated documentation files (the "Software"), 00006 * to deal in the Software without restriction, including without limitation 00007 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00008 * and/or sell copies of the Software, and to permit persons to whom the 00009 * Software is furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included 00012 * in all copies or substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00015 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00017 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES 00018 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00019 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00020 * OTHER DEALINGS IN THE SOFTWARE. 00021 * 00022 * Except as contained in this notice, the name of Maxim Integrated 00023 * Products, Inc. shall not be used except as stated in the Maxim Integrated 00024 * Products, Inc. Branding Policy. 00025 * 00026 * The mere transfer of this software does not imply any licenses 00027 * of trade secrets, proprietary technology, copyrights, patents, 00028 * trademarks, maskwork rights, or any other form of intellectual 00029 * property whatsoever. Maxim Integrated Products, Inc. retains all 00030 * ownership rights. 00031 *******************************************************************************/ 00032 00033 #ifndef MaximInterface_span 00034 #define MaximInterface_span 00035 00036 #include <stddef.h> 00037 #include <algorithm> 00038 #include <iterator> 00039 #include <vector> 00040 #include "array.hpp" 00041 #include "type_traits.hpp" 00042 00043 namespace MaximInterface { 00044 00045 static const ptrdiff_t dynamic_extent = -1; 00046 00047 struct with_container_t { 00048 explicit with_container_t(int) {} 00049 }; 00050 00051 static const with_container_t with_container(0); 00052 00053 namespace detail { 00054 00055 template <template <typename, ptrdiff_t = MaximInterface::dynamic_extent> 00056 class span, 00057 typename T, ptrdiff_t Extent> 00058 class span_base { 00059 public: 00060 typedef T element_type; 00061 typedef typename remove_cv<element_type>::type value_type; 00062 typedef ptrdiff_t index_type; 00063 typedef ptrdiff_t difference_type; 00064 typedef element_type * pointer; 00065 typedef element_type & reference; 00066 typedef element_type * iterator; 00067 typedef const element_type * const_iterator; 00068 typedef std::reverse_iterator<iterator> reverse_iterator; 00069 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 00070 00071 static const index_type extent = Extent; 00072 00073 protected: 00074 span_base(pointer data) : data_(data) {} 00075 ~span_base() {} 00076 00077 public: 00078 /// @name Iterators 00079 /// @{ 00080 00081 iterator begin() const { 00082 return const_cast<iterator>(static_cast<const span_base &>(*this).cbegin()); 00083 } 00084 00085 const_iterator cbegin() const { return data(); } 00086 00087 iterator end() const { 00088 return const_cast<iterator>(static_cast<const span_base &>(*this).cend()); 00089 } 00090 00091 const_iterator cend() const { return cbegin() + size(); } 00092 00093 reverse_iterator rbegin() const { return reverse_iterator(end()); } 00094 00095 const_reverse_iterator crbegin() const { 00096 return const_reverse_iterator(cend()); 00097 } 00098 00099 reverse_iterator rend() const { return reverse_iterator(begin()); } 00100 00101 const_reverse_iterator crend() const { 00102 return const_reverse_iterator(cbegin()); 00103 } 00104 00105 /// @} 00106 00107 /// @name Element access 00108 /// @{ 00109 00110 reference operator[](index_type idx) const { return data()[idx]; } 00111 00112 reference operator()(index_type idx) const { return operator[](idx); } 00113 00114 pointer data() const { return data_; } 00115 00116 /// @} 00117 00118 /// @name Subviews 00119 /// @{ 00120 00121 template <index_type Count> span<element_type, Count> first() const { 00122 return subspan<0, Count>(); 00123 } 00124 00125 span<element_type> first(index_type Count) const { return subspan(0, Count); } 00126 00127 span<element_type> last(index_type Count) const { 00128 return subspan(size() - Count, Count); 00129 } 00130 00131 template <index_type Offset, index_type Count> 00132 span<element_type, Count> subspan() const { 00133 return span<element_type, Count>(data() + Offset, Count); 00134 } 00135 00136 span<element_type> subspan(index_type Offset, 00137 index_type Count = dynamic_extent) const { 00138 return span<element_type>( 00139 data() + Offset, Count == dynamic_extent ? size() - Offset : Count); 00140 } 00141 00142 /// @} 00143 00144 private: 00145 index_type size() const { 00146 return static_cast<const span<T, Extent> &>(*this).size(); 00147 } 00148 00149 pointer data_; 00150 }; 00151 00152 } // namespace detail 00153 00154 /// Generic memory span class similar to gsl::span or the proposed std::span. 00155 template <typename T, ptrdiff_t Extent = dynamic_extent> 00156 class span : public detail::span_base<MaximInterface::span, T, Extent> { 00157 typedef detail::span_base<MaximInterface::span, T, Extent> span_base; 00158 00159 public: 00160 using span_base::extent; 00161 using typename span_base::element_type; 00162 using typename span_base::index_type; 00163 using typename span_base::pointer; 00164 using typename span_base::value_type; 00165 00166 span(pointer data, index_type) : span_base(data) {} 00167 00168 span(pointer begin, pointer) : span_base(begin) {} 00169 00170 span(element_type (&arr)[extent]) : span_base(arr) {} 00171 00172 span(array<value_type, extent> & arr) : span_base(arr.data()) {} 00173 00174 span(const array<value_type, extent> & arr) : span_base(arr.data()) {} 00175 00176 template <typename U> span(const span<U, extent> & s) : span_base(s.data()) {} 00177 00178 template <typename Allocator> 00179 explicit span(std::vector<value_type, Allocator> & vec) 00180 : span_base(&vec.front()) {} 00181 00182 template <typename Allocator> 00183 explicit span(const std::vector<value_type, Allocator> & vec) 00184 : span_base(&vec.front()) {} 00185 00186 template <typename Container> 00187 span(with_container_t, Container & cont) : span_base(cont.data()) {} 00188 00189 template <typename Container> 00190 span(with_container_t, const Container & cont) : span_base(cont.data()) {} 00191 00192 /// @name Observers 00193 /// @{ 00194 00195 static index_type size() { return extent; } 00196 00197 static index_type size_bytes() { return size() * sizeof(element_type); } 00198 00199 static bool empty() { return size() == 0; } 00200 00201 /// @} 00202 00203 /// @name Subviews 00204 /// @{ 00205 00206 template <index_type Count> span<element_type, Count> last() const { 00207 return this->template subspan<extent - Count, Count>(); 00208 } 00209 00210 /// @} 00211 }; 00212 00213 template <typename T> 00214 class span<T, dynamic_extent> 00215 : public detail::span_base<MaximInterface::span, T, dynamic_extent> { 00216 typedef detail::span_base<MaximInterface::span, T, dynamic_extent> span_base; 00217 00218 public: 00219 using typename span_base::element_type; 00220 using typename span_base::index_type; 00221 using typename span_base::pointer; 00222 using typename span_base::value_type; 00223 00224 span() : span_base(NULL), size_(0) {} 00225 00226 span(pointer data, index_type size) : span_base(data), size_(size) {} 00227 00228 span(pointer begin, pointer end) : span_base(begin), size_(end - begin) {} 00229 00230 template <size_t N> span(element_type (&arr)[N]) : span_base(arr), size_(N) {} 00231 00232 template <size_t N> 00233 span(array<value_type, N> & arr) : span_base(arr.data()), size_(N) {} 00234 00235 template <size_t N> 00236 span(const array<value_type, N> & arr) : span_base(arr.data()), size_(N) {} 00237 00238 template <typename U, ptrdiff_t N> 00239 span(const span<U, N> & s) : span_base(s.data()), size_(s.size()) {} 00240 00241 template <typename Allocator> 00242 span(std::vector<value_type, Allocator> & vec) 00243 : span_base(vec.empty() ? NULL : &vec.front()), size_(vec.size()) {} 00244 00245 template <typename Allocator> 00246 span(const std::vector<value_type, Allocator> & vec) 00247 : span_base(vec.empty() ? NULL : &vec.front()), size_(vec.size()) {} 00248 00249 template <typename Container> 00250 span(with_container_t, Container & cont) 00251 : span_base(cont.data()), size_(cont.size()) {} 00252 00253 template <typename Container> 00254 span(with_container_t, const Container & cont) 00255 : span_base(cont.data()), size_(cont.size()) {} 00256 00257 /// @name Observers 00258 /// @{ 00259 00260 index_type size() const { return size_; } 00261 00262 index_type size_bytes() const { return size() * sizeof(element_type); } 00263 00264 bool empty() const { return size() == 0; } 00265 00266 /// @} 00267 00268 /// @name Subviews 00269 /// @{ 00270 00271 template <index_type Count> span<element_type, Count> last() const { 00272 return span<element_type, Count>(this->data() + (size() - Count), Count); 00273 } 00274 00275 /// @} 00276 00277 private: 00278 index_type size_; 00279 }; 00280 00281 template <typename T, ptrdiff_t Extent, typename U> 00282 bool operator==(span<T, Extent> lhs, span<U, Extent> rhs) { 00283 return lhs.size() == rhs.size() && 00284 std::equal(lhs.begin(), lhs.end(), rhs.begin()); 00285 } 00286 00287 template <typename T, ptrdiff_t Extent, typename U> 00288 bool operator!=(span<T, Extent> lhs, span<U, Extent> rhs) { 00289 return !operator==(lhs, rhs); 00290 } 00291 00292 template <typename T, ptrdiff_t Extent, typename U> 00293 bool operator<(span<T, Extent> lhs, span<U, Extent> rhs) { 00294 return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), 00295 rhs.end()); 00296 } 00297 00298 template <typename T, ptrdiff_t Extent, typename U> 00299 bool operator>(span<T, Extent> lhs, span<U, Extent> rhs) { 00300 return operator<(rhs, lhs); 00301 } 00302 00303 template <typename T, ptrdiff_t Extent, typename U> 00304 bool operator<=(span<T, Extent> lhs, span<U, Extent> rhs) { 00305 return !operator>(lhs, rhs); 00306 } 00307 00308 template <typename T, ptrdiff_t Extent, typename U> 00309 bool operator>=(span<T, Extent> lhs, span<U, Extent> rhs) { 00310 return !operator<(lhs, rhs); 00311 } 00312 00313 template <typename T> 00314 span<T> make_span(T * data, typename span<T>::index_type size) { 00315 return span<T>(data, size); 00316 } 00317 00318 template <typename T> span<T> make_span(T * begin, T * end) { 00319 return span<T>(begin, end); 00320 } 00321 00322 template <typename T, size_t N> span<T, N> make_span(T (&arr)[N]) { 00323 return span<T, N>(arr); 00324 } 00325 00326 template <typename T, size_t N> span<T, N> make_span(array<T, N> & arr) { 00327 return arr; 00328 } 00329 00330 template <typename T, size_t N> 00331 span<const T, N> make_span(const array<T, N> & arr) { 00332 return arr; 00333 } 00334 00335 template <typename T, typename Allocator> 00336 span<T> make_span(std::vector<T, Allocator> & vec) { 00337 return vec; 00338 } 00339 00340 template <typename T, typename Allocator> 00341 span<const T> make_span(const std::vector<T, Allocator> & vec) { 00342 return vec; 00343 } 00344 00345 template <typename Container> 00346 span<typename Container::value_type> make_span(with_container_t, 00347 Container & cont) { 00348 return span<typename Container::value_type>(with_container, cont); 00349 } 00350 00351 template <typename Container> 00352 span<const typename Container::value_type> make_span(with_container_t, 00353 const Container & cont) { 00354 return span<const typename Container::value_type>(with_container, cont); 00355 } 00356 00357 /// Deep copy between static spans of the same size. 00358 template <typename T, ptrdiff_t Extent, typename U> 00359 typename enable_if<Extent != dynamic_extent>::type copy(span<T, Extent> src, 00360 span<U, Extent> dst) { 00361 std::copy(src.begin(), src.end(), dst.begin()); 00362 } 00363 00364 } // namespace MaximInterface 00365 00366 #endif
Generated on Tue Jul 12 2022 23:29:45 by
1.7.2