Device interface library for multiple platforms including Mbed.

Dependents:   DeepCover Embedded Security in IoT MaximInterface MAXREFDES155#

Maxim Interface is a library framework focused on providing flexible and expressive hardware interfaces. Both communication interfaces such as I2C and 1-Wire and device interfaces such as DS18B20 are supported. Modern C++ concepts are used extensively while keeping compatibility with C++98/C++03 and requiring no external dependencies. The embedded-friendly design does not depend on exceptions or RTTI.

The full version of the project is hosted on GitLab: https://gitlab.com/iabenz/MaximInterface

Committer:
IanBenzMaxim
Date:
Mon Sep 16 11:13:37 2019 -0500
Revision:
8:5ea891c7d1a1
Parent:
7:9cd16581b578
Child:
10:947d3f44e0a0
Updated to version 2.0.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
IanBenzMaxim 7:9cd16581b578 1 /*******************************************************************************
IanBenzMaxim 8:5ea891c7d1a1 2 * Copyright (C) Maxim Integrated Products, Inc., All Rights Reserved.
IanBenzMaxim 7:9cd16581b578 3 *
IanBenzMaxim 7:9cd16581b578 4 * Permission is hereby granted, free of charge, to any person obtaining a
IanBenzMaxim 7:9cd16581b578 5 * copy of this software and associated documentation files (the "Software"),
IanBenzMaxim 7:9cd16581b578 6 * to deal in the Software without restriction, including without limitation
IanBenzMaxim 7:9cd16581b578 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
IanBenzMaxim 7:9cd16581b578 8 * and/or sell copies of the Software, and to permit persons to whom the
IanBenzMaxim 7:9cd16581b578 9 * Software is furnished to do so, subject to the following conditions:
IanBenzMaxim 7:9cd16581b578 10 *
IanBenzMaxim 7:9cd16581b578 11 * The above copyright notice and this permission notice shall be included
IanBenzMaxim 7:9cd16581b578 12 * in all copies or substantial portions of the Software.
IanBenzMaxim 7:9cd16581b578 13 *
IanBenzMaxim 7:9cd16581b578 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
IanBenzMaxim 7:9cd16581b578 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
IanBenzMaxim 7:9cd16581b578 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IanBenzMaxim 7:9cd16581b578 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
IanBenzMaxim 7:9cd16581b578 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
IanBenzMaxim 7:9cd16581b578 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
IanBenzMaxim 7:9cd16581b578 20 * OTHER DEALINGS IN THE SOFTWARE.
IanBenzMaxim 7:9cd16581b578 21 *
IanBenzMaxim 7:9cd16581b578 22 * Except as contained in this notice, the name of Maxim Integrated
IanBenzMaxim 7:9cd16581b578 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
IanBenzMaxim 7:9cd16581b578 24 * Products, Inc. Branding Policy.
IanBenzMaxim 7:9cd16581b578 25 *
IanBenzMaxim 7:9cd16581b578 26 * The mere transfer of this software does not imply any licenses
IanBenzMaxim 7:9cd16581b578 27 * of trade secrets, proprietary technology, copyrights, patents,
IanBenzMaxim 7:9cd16581b578 28 * trademarks, maskwork rights, or any other form of intellectual
IanBenzMaxim 7:9cd16581b578 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
IanBenzMaxim 7:9cd16581b578 30 * ownership rights.
IanBenzMaxim 7:9cd16581b578 31 *******************************************************************************/
IanBenzMaxim 7:9cd16581b578 32
IanBenzMaxim 8:5ea891c7d1a1 33 #ifndef MaximInterfaceCore_span_hpp
IanBenzMaxim 8:5ea891c7d1a1 34 #define MaximInterfaceCore_span_hpp
IanBenzMaxim 7:9cd16581b578 35
IanBenzMaxim 7:9cd16581b578 36 #include <stddef.h>
IanBenzMaxim 7:9cd16581b578 37 #include <iterator>
IanBenzMaxim 7:9cd16581b578 38 #include <vector>
IanBenzMaxim 7:9cd16581b578 39 #include "array.hpp"
IanBenzMaxim 7:9cd16581b578 40 #include "type_traits.hpp"
IanBenzMaxim 7:9cd16581b578 41
IanBenzMaxim 7:9cd16581b578 42 namespace MaximInterfaceCore {
IanBenzMaxim 7:9cd16581b578 43
IanBenzMaxim 7:9cd16581b578 44 /// Differentiates spans of static and dynamic extent.
IanBenzMaxim 8:5ea891c7d1a1 45 static const size_t dynamic_extent = static_cast<size_t>(-1); // SIZE_MAX
IanBenzMaxim 7:9cd16581b578 46
IanBenzMaxim 7:9cd16581b578 47 /// @brief
IanBenzMaxim 7:9cd16581b578 48 /// Generic memory span class similar to gsl::span and the proposed std::span.
IanBenzMaxim 7:9cd16581b578 49 /// @note
IanBenzMaxim 7:9cd16581b578 50 /// Separate implementations are used for spans of static and dynamic extent.
IanBenzMaxim 7:9cd16581b578 51 template <typename T, size_t Extent = dynamic_extent> class span;
IanBenzMaxim 7:9cd16581b578 52
IanBenzMaxim 7:9cd16581b578 53 namespace detail {
IanBenzMaxim 7:9cd16581b578 54
IanBenzMaxim 7:9cd16581b578 55 // Implementation of common span functionality using CRTP.
IanBenzMaxim 7:9cd16581b578 56 template <template <typename, size_t = MaximInterfaceCore::dynamic_extent>
IanBenzMaxim 7:9cd16581b578 57 class span,
IanBenzMaxim 7:9cd16581b578 58 typename T, size_t Extent>
IanBenzMaxim 7:9cd16581b578 59 class span_base {
IanBenzMaxim 7:9cd16581b578 60 public:
IanBenzMaxim 7:9cd16581b578 61 typedef T element_type;
IanBenzMaxim 7:9cd16581b578 62 typedef typename remove_cv<element_type>::type value_type;
IanBenzMaxim 7:9cd16581b578 63 typedef size_t index_type;
IanBenzMaxim 7:9cd16581b578 64 typedef ptrdiff_t difference_type;
IanBenzMaxim 7:9cd16581b578 65 typedef element_type * pointer;
IanBenzMaxim 7:9cd16581b578 66 typedef const element_type * const_pointer;
IanBenzMaxim 7:9cd16581b578 67 typedef element_type & reference;
IanBenzMaxim 7:9cd16581b578 68 typedef const element_type & const_reference;
IanBenzMaxim 7:9cd16581b578 69 typedef element_type * iterator;
IanBenzMaxim 7:9cd16581b578 70 typedef const element_type * const_iterator;
IanBenzMaxim 7:9cd16581b578 71 typedef std::reverse_iterator<iterator> reverse_iterator;
IanBenzMaxim 7:9cd16581b578 72 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
IanBenzMaxim 7:9cd16581b578 73
IanBenzMaxim 7:9cd16581b578 74 static const index_type extent = Extent;
IanBenzMaxim 7:9cd16581b578 75
IanBenzMaxim 7:9cd16581b578 76 protected:
IanBenzMaxim 7:9cd16581b578 77 span_base(pointer data) : data_(data) {}
IanBenzMaxim 7:9cd16581b578 78 ~span_base() {}
IanBenzMaxim 7:9cd16581b578 79
IanBenzMaxim 7:9cd16581b578 80 public:
IanBenzMaxim 7:9cd16581b578 81 /// @name Iterators
IanBenzMaxim 7:9cd16581b578 82 /// @{
IanBenzMaxim 7:9cd16581b578 83
IanBenzMaxim 7:9cd16581b578 84 iterator begin() const {
IanBenzMaxim 7:9cd16581b578 85 return const_cast<iterator>(static_cast<const span_base &>(*this).cbegin());
IanBenzMaxim 7:9cd16581b578 86 }
IanBenzMaxim 7:9cd16581b578 87
IanBenzMaxim 7:9cd16581b578 88 const_iterator cbegin() const { return data(); }
IanBenzMaxim 7:9cd16581b578 89
IanBenzMaxim 7:9cd16581b578 90 iterator end() const {
IanBenzMaxim 7:9cd16581b578 91 return const_cast<iterator>(static_cast<const span_base &>(*this).cend());
IanBenzMaxim 7:9cd16581b578 92 }
IanBenzMaxim 7:9cd16581b578 93
IanBenzMaxim 7:9cd16581b578 94 const_iterator cend() const { return cbegin() + size(); }
IanBenzMaxim 7:9cd16581b578 95
IanBenzMaxim 7:9cd16581b578 96 reverse_iterator rbegin() const { return reverse_iterator(end()); }
IanBenzMaxim 7:9cd16581b578 97
IanBenzMaxim 7:9cd16581b578 98 const_reverse_iterator crbegin() const {
IanBenzMaxim 7:9cd16581b578 99 return const_reverse_iterator(cend());
IanBenzMaxim 7:9cd16581b578 100 }
IanBenzMaxim 7:9cd16581b578 101
IanBenzMaxim 7:9cd16581b578 102 reverse_iterator rend() const { return reverse_iterator(begin()); }
IanBenzMaxim 7:9cd16581b578 103
IanBenzMaxim 7:9cd16581b578 104 const_reverse_iterator crend() const {
IanBenzMaxim 7:9cd16581b578 105 return const_reverse_iterator(cbegin());
IanBenzMaxim 7:9cd16581b578 106 }
IanBenzMaxim 7:9cd16581b578 107
IanBenzMaxim 7:9cd16581b578 108 /// @}
IanBenzMaxim 7:9cd16581b578 109
IanBenzMaxim 7:9cd16581b578 110 /// @name Element access
IanBenzMaxim 7:9cd16581b578 111 /// @{
IanBenzMaxim 7:9cd16581b578 112
IanBenzMaxim 7:9cd16581b578 113 reference front() const { return operator[](0); }
IanBenzMaxim 7:9cd16581b578 114
IanBenzMaxim 7:9cd16581b578 115 reference back() const { return operator[](size() - 1); }
IanBenzMaxim 7:9cd16581b578 116
IanBenzMaxim 7:9cd16581b578 117 reference operator[](index_type idx) const { return data()[idx]; }
IanBenzMaxim 7:9cd16581b578 118
IanBenzMaxim 7:9cd16581b578 119 pointer data() const { return data_; }
IanBenzMaxim 7:9cd16581b578 120
IanBenzMaxim 7:9cd16581b578 121 /// @}
IanBenzMaxim 7:9cd16581b578 122
IanBenzMaxim 7:9cd16581b578 123 /// @name Subviews
IanBenzMaxim 7:9cd16581b578 124 /// @{
IanBenzMaxim 7:9cd16581b578 125
IanBenzMaxim 7:9cd16581b578 126 template <index_type Count> span<element_type, Count> first() const {
IanBenzMaxim 7:9cd16581b578 127 return subspan<0, Count>();
IanBenzMaxim 7:9cd16581b578 128 }
IanBenzMaxim 7:9cd16581b578 129
IanBenzMaxim 7:9cd16581b578 130 span<element_type> first(index_type Count) const { return subspan(0, Count); }
IanBenzMaxim 7:9cd16581b578 131
IanBenzMaxim 7:9cd16581b578 132 span<element_type> last(index_type Count) const {
IanBenzMaxim 7:9cd16581b578 133 return subspan(size() - Count, Count);
IanBenzMaxim 7:9cd16581b578 134 }
IanBenzMaxim 7:9cd16581b578 135
IanBenzMaxim 7:9cd16581b578 136 template <index_type Offset, index_type Count>
IanBenzMaxim 7:9cd16581b578 137 span<element_type, Count> subspan() const {
IanBenzMaxim 7:9cd16581b578 138 return span<element_type, Count>(data() + Offset, Count);
IanBenzMaxim 7:9cd16581b578 139 }
IanBenzMaxim 7:9cd16581b578 140
IanBenzMaxim 7:9cd16581b578 141 span<element_type> subspan(index_type Offset,
IanBenzMaxim 7:9cd16581b578 142 index_type Count = dynamic_extent) const {
IanBenzMaxim 7:9cd16581b578 143 return span<element_type>(
IanBenzMaxim 7:9cd16581b578 144 data() + Offset, Count == dynamic_extent ? size() - Offset : Count);
IanBenzMaxim 7:9cd16581b578 145 }
IanBenzMaxim 7:9cd16581b578 146
IanBenzMaxim 7:9cd16581b578 147 /// @}
IanBenzMaxim 7:9cd16581b578 148
IanBenzMaxim 7:9cd16581b578 149 private:
IanBenzMaxim 7:9cd16581b578 150 index_type size() const {
IanBenzMaxim 7:9cd16581b578 151 return static_cast<const span<T, Extent> &>(*this).size();
IanBenzMaxim 7:9cd16581b578 152 }
IanBenzMaxim 7:9cd16581b578 153
IanBenzMaxim 7:9cd16581b578 154 pointer data_;
IanBenzMaxim 7:9cd16581b578 155 };
IanBenzMaxim 7:9cd16581b578 156
IanBenzMaxim 8:5ea891c7d1a1 157 template <template <typename, size_t> class span, typename T, size_t Extent>
IanBenzMaxim 8:5ea891c7d1a1 158 const typename span_base<span, T, Extent>::index_type
IanBenzMaxim 8:5ea891c7d1a1 159 span_base<span, T, Extent>::extent;
IanBenzMaxim 8:5ea891c7d1a1 160
IanBenzMaxim 8:5ea891c7d1a1 161 template <typename T> class has_data {
IanBenzMaxim 8:5ea891c7d1a1 162 typedef char true_type[1];
IanBenzMaxim 8:5ea891c7d1a1 163 typedef char false_type[2];
IanBenzMaxim 8:5ea891c7d1a1 164
IanBenzMaxim 8:5ea891c7d1a1 165 template <typename U, U> struct check;
IanBenzMaxim 8:5ea891c7d1a1 166
IanBenzMaxim 8:5ea891c7d1a1 167 template <typename U>
IanBenzMaxim 8:5ea891c7d1a1 168 static true_type & test(check<typename U::pointer (U::*)(), &U::data> *);
IanBenzMaxim 8:5ea891c7d1a1 169
IanBenzMaxim 8:5ea891c7d1a1 170 template <typename> static false_type & test(...);
IanBenzMaxim 8:5ea891c7d1a1 171
IanBenzMaxim 8:5ea891c7d1a1 172 public:
IanBenzMaxim 8:5ea891c7d1a1 173 static const bool value = (sizeof(test<T>(NULL)) == sizeof(true_type));
IanBenzMaxim 8:5ea891c7d1a1 174 };
IanBenzMaxim 8:5ea891c7d1a1 175
IanBenzMaxim 8:5ea891c7d1a1 176 template <typename T> class has_data<const T> {
IanBenzMaxim 8:5ea891c7d1a1 177 typedef char true_type[1];
IanBenzMaxim 8:5ea891c7d1a1 178 typedef char false_type[2];
IanBenzMaxim 8:5ea891c7d1a1 179
IanBenzMaxim 8:5ea891c7d1a1 180 template <typename U, U> struct check;
IanBenzMaxim 7:9cd16581b578 181
IanBenzMaxim 8:5ea891c7d1a1 182 template <typename U>
IanBenzMaxim 8:5ea891c7d1a1 183 static true_type &
IanBenzMaxim 8:5ea891c7d1a1 184 test(check<typename U::const_pointer (U::*)() const, &U::data> *);
IanBenzMaxim 8:5ea891c7d1a1 185
IanBenzMaxim 8:5ea891c7d1a1 186 template <typename> static false_type & test(...);
IanBenzMaxim 8:5ea891c7d1a1 187
IanBenzMaxim 8:5ea891c7d1a1 188 public:
IanBenzMaxim 8:5ea891c7d1a1 189 static const bool value = (sizeof(test<T>(NULL)) == sizeof(true_type));
IanBenzMaxim 8:5ea891c7d1a1 190 };
IanBenzMaxim 8:5ea891c7d1a1 191
IanBenzMaxim 8:5ea891c7d1a1 192 template <typename T> class has_size {
IanBenzMaxim 8:5ea891c7d1a1 193 typedef char true_type[1];
IanBenzMaxim 8:5ea891c7d1a1 194 typedef char false_type[2];
IanBenzMaxim 7:9cd16581b578 195
IanBenzMaxim 8:5ea891c7d1a1 196 template <typename U, U> struct check;
IanBenzMaxim 8:5ea891c7d1a1 197
IanBenzMaxim 8:5ea891c7d1a1 198 template <typename U>
IanBenzMaxim 8:5ea891c7d1a1 199 static true_type &
IanBenzMaxim 8:5ea891c7d1a1 200 test(check<typename U::size_type (U::*)() const, &U::size> *);
IanBenzMaxim 8:5ea891c7d1a1 201
IanBenzMaxim 8:5ea891c7d1a1 202 // Additionally support a static member function.
IanBenzMaxim 8:5ea891c7d1a1 203 template <typename U>
IanBenzMaxim 8:5ea891c7d1a1 204 static true_type & test(check<typename U::size_type (*)(), &U::size> *);
IanBenzMaxim 8:5ea891c7d1a1 205
IanBenzMaxim 8:5ea891c7d1a1 206 template <typename> static false_type & test(...);
IanBenzMaxim 8:5ea891c7d1a1 207
IanBenzMaxim 8:5ea891c7d1a1 208 public:
IanBenzMaxim 8:5ea891c7d1a1 209 static const bool value = (sizeof(test<T>(NULL)) == sizeof(true_type));
IanBenzMaxim 8:5ea891c7d1a1 210 };
IanBenzMaxim 7:9cd16581b578 211
IanBenzMaxim 7:9cd16581b578 212 template <typename T> struct is_array_class_helper : false_type {};
IanBenzMaxim 7:9cd16581b578 213
IanBenzMaxim 7:9cd16581b578 214 template <typename T, size_t N>
IanBenzMaxim 7:9cd16581b578 215 struct is_array_class_helper<array<T, N> > : true_type {};
IanBenzMaxim 7:9cd16581b578 216
IanBenzMaxim 7:9cd16581b578 217 template <typename T>
IanBenzMaxim 7:9cd16581b578 218 struct is_array_class : is_array_class_helper<typename remove_cv<T>::type> {};
IanBenzMaxim 7:9cd16581b578 219
IanBenzMaxim 7:9cd16581b578 220 template <typename T> struct is_span_helper : false_type {};
IanBenzMaxim 7:9cd16581b578 221
IanBenzMaxim 7:9cd16581b578 222 template <typename T, size_t Extent>
IanBenzMaxim 7:9cd16581b578 223 struct is_span_helper<span<T, Extent> > : true_type {};
IanBenzMaxim 7:9cd16581b578 224
IanBenzMaxim 7:9cd16581b578 225 template <typename T>
IanBenzMaxim 7:9cd16581b578 226 struct is_span : is_span_helper<typename remove_cv<T>::type> {};
IanBenzMaxim 7:9cd16581b578 227
IanBenzMaxim 7:9cd16581b578 228 template <typename T> struct is_vector_helper : false_type {};
IanBenzMaxim 7:9cd16581b578 229
IanBenzMaxim 7:9cd16581b578 230 template <typename T, typename Allocator>
IanBenzMaxim 7:9cd16581b578 231 struct is_vector_helper<std::vector<T, Allocator> > : true_type {};
IanBenzMaxim 7:9cd16581b578 232
IanBenzMaxim 7:9cd16581b578 233 template <typename T>
IanBenzMaxim 7:9cd16581b578 234 struct is_vector : is_vector_helper<typename remove_cv<T>::type> {};
IanBenzMaxim 7:9cd16581b578 235
IanBenzMaxim 8:5ea891c7d1a1 236 // Used to disable the span container constructors.
IanBenzMaxim 7:9cd16581b578 237 template <typename T>
IanBenzMaxim 8:5ea891c7d1a1 238 struct enable_if_span_convertible
IanBenzMaxim 8:5ea891c7d1a1 239 : enable_if<has_data<T>::value && has_size<T>::value &&
IanBenzMaxim 8:5ea891c7d1a1 240 !(is_array_class<T>::value || is_span<T>::value ||
IanBenzMaxim 7:9cd16581b578 241 is_vector<T>::value)> {};
IanBenzMaxim 7:9cd16581b578 242
IanBenzMaxim 7:9cd16581b578 243 } // namespace detail
IanBenzMaxim 7:9cd16581b578 244
IanBenzMaxim 7:9cd16581b578 245 // Implementation of the static extent span.
IanBenzMaxim 7:9cd16581b578 246 template <typename T, size_t Extent>
IanBenzMaxim 7:9cd16581b578 247 class span : public detail::span_base<MaximInterfaceCore::span, T, Extent> {
IanBenzMaxim 7:9cd16581b578 248 typedef detail::span_base<MaximInterfaceCore::span, T, Extent> span_base;
IanBenzMaxim 7:9cd16581b578 249
IanBenzMaxim 7:9cd16581b578 250 public:
IanBenzMaxim 7:9cd16581b578 251 using span_base::extent;
IanBenzMaxim 7:9cd16581b578 252 using typename span_base::element_type;
IanBenzMaxim 7:9cd16581b578 253 using typename span_base::index_type;
IanBenzMaxim 7:9cd16581b578 254 using typename span_base::pointer;
IanBenzMaxim 7:9cd16581b578 255 using typename span_base::value_type;
IanBenzMaxim 7:9cd16581b578 256
IanBenzMaxim 7:9cd16581b578 257 span(pointer data, index_type) : span_base(data) {}
IanBenzMaxim 7:9cd16581b578 258
IanBenzMaxim 7:9cd16581b578 259 span(pointer begin, pointer) : span_base(begin) {}
IanBenzMaxim 7:9cd16581b578 260
IanBenzMaxim 7:9cd16581b578 261 span(element_type (&arr)[extent]) : span_base(arr) {}
IanBenzMaxim 7:9cd16581b578 262
IanBenzMaxim 7:9cd16581b578 263 span(array<value_type, extent> & arr) : span_base(arr.data()) {}
IanBenzMaxim 7:9cd16581b578 264
IanBenzMaxim 7:9cd16581b578 265 span(const array<value_type, extent> & arr) : span_base(arr.data()) {}
IanBenzMaxim 7:9cd16581b578 266
IanBenzMaxim 7:9cd16581b578 267 template <typename U> span(const span<U, extent> & s) : span_base(s.data()) {}
IanBenzMaxim 7:9cd16581b578 268
IanBenzMaxim 7:9cd16581b578 269 template <typename Allocator>
IanBenzMaxim 7:9cd16581b578 270 span(std::vector<value_type, Allocator> & vec) : span_base(&vec.front()) {}
IanBenzMaxim 7:9cd16581b578 271
IanBenzMaxim 7:9cd16581b578 272 template <typename Allocator>
IanBenzMaxim 7:9cd16581b578 273 span(const std::vector<value_type, Allocator> & vec)
IanBenzMaxim 7:9cd16581b578 274 : span_base(&vec.front()) {}
IanBenzMaxim 7:9cd16581b578 275
IanBenzMaxim 7:9cd16581b578 276 template <typename Container>
IanBenzMaxim 7:9cd16581b578 277 span(Container & cont,
IanBenzMaxim 8:5ea891c7d1a1 278 typename detail::enable_if_span_convertible<Container>::type * = NULL)
IanBenzMaxim 7:9cd16581b578 279 : span_base(cont.data()) {}
IanBenzMaxim 7:9cd16581b578 280
IanBenzMaxim 7:9cd16581b578 281 template <typename Container>
IanBenzMaxim 7:9cd16581b578 282 span(const Container & cont,
IanBenzMaxim 8:5ea891c7d1a1 283 typename detail::enable_if_span_convertible<const Container>::type * =
IanBenzMaxim 7:9cd16581b578 284 NULL)
IanBenzMaxim 7:9cd16581b578 285 : span_base(cont.data()) {}
IanBenzMaxim 7:9cd16581b578 286
IanBenzMaxim 7:9cd16581b578 287 /// @name Observers
IanBenzMaxim 7:9cd16581b578 288 /// @{
IanBenzMaxim 7:9cd16581b578 289
IanBenzMaxim 7:9cd16581b578 290 static index_type size() { return extent; }
IanBenzMaxim 7:9cd16581b578 291
IanBenzMaxim 7:9cd16581b578 292 static index_type size_bytes() { return size() * sizeof(element_type); }
IanBenzMaxim 7:9cd16581b578 293
IanBenzMaxim 7:9cd16581b578 294 static bool empty() { return size() == 0; }
IanBenzMaxim 7:9cd16581b578 295
IanBenzMaxim 7:9cd16581b578 296 /// @}
IanBenzMaxim 7:9cd16581b578 297
IanBenzMaxim 7:9cd16581b578 298 /// @name Subviews
IanBenzMaxim 7:9cd16581b578 299 /// @{
IanBenzMaxim 7:9cd16581b578 300
IanBenzMaxim 7:9cd16581b578 301 template <index_type Count> span<element_type, Count> last() const {
IanBenzMaxim 7:9cd16581b578 302 return this->template subspan<extent - Count, Count>();
IanBenzMaxim 7:9cd16581b578 303 }
IanBenzMaxim 7:9cd16581b578 304
IanBenzMaxim 7:9cd16581b578 305 /// @}
IanBenzMaxim 7:9cd16581b578 306 };
IanBenzMaxim 7:9cd16581b578 307
IanBenzMaxim 7:9cd16581b578 308 // Implementation of the dynamic extent span.
IanBenzMaxim 7:9cd16581b578 309 template <typename T>
IanBenzMaxim 7:9cd16581b578 310 class span<T, dynamic_extent>
IanBenzMaxim 7:9cd16581b578 311 : public detail::span_base<MaximInterfaceCore::span, T, dynamic_extent> {
IanBenzMaxim 7:9cd16581b578 312 typedef detail::span_base<MaximInterfaceCore::span, T, dynamic_extent>
IanBenzMaxim 7:9cd16581b578 313 span_base;
IanBenzMaxim 7:9cd16581b578 314
IanBenzMaxim 7:9cd16581b578 315 public:
IanBenzMaxim 7:9cd16581b578 316 using typename span_base::element_type;
IanBenzMaxim 7:9cd16581b578 317 using typename span_base::index_type;
IanBenzMaxim 7:9cd16581b578 318 using typename span_base::pointer;
IanBenzMaxim 7:9cd16581b578 319 using typename span_base::value_type;
IanBenzMaxim 7:9cd16581b578 320
IanBenzMaxim 7:9cd16581b578 321 span() : span_base(NULL), size_(0) {}
IanBenzMaxim 7:9cd16581b578 322
IanBenzMaxim 7:9cd16581b578 323 span(pointer data, index_type size) : span_base(data), size_(size) {}
IanBenzMaxim 7:9cd16581b578 324
IanBenzMaxim 7:9cd16581b578 325 span(pointer begin, pointer end) : span_base(begin), size_(end - begin) {}
IanBenzMaxim 7:9cd16581b578 326
IanBenzMaxim 7:9cd16581b578 327 template <size_t N> span(element_type (&arr)[N]) : span_base(arr), size_(N) {}
IanBenzMaxim 7:9cd16581b578 328
IanBenzMaxim 8:5ea891c7d1a1 329 template <size_t N>
IanBenzMaxim 8:5ea891c7d1a1 330 span(array<value_type, N> & arr) : span_base(arr.data()), size_(N) {}
IanBenzMaxim 8:5ea891c7d1a1 331
IanBenzMaxim 8:5ea891c7d1a1 332 template <size_t N>
IanBenzMaxim 8:5ea891c7d1a1 333 span(const array<value_type, N> & arr) : span_base(arr.data()), size_(N) {}
IanBenzMaxim 8:5ea891c7d1a1 334
IanBenzMaxim 7:9cd16581b578 335 template <typename U, size_t N>
IanBenzMaxim 7:9cd16581b578 336 span(const span<U, N> & s) : span_base(s.data()), size_(s.size()) {}
IanBenzMaxim 7:9cd16581b578 337
IanBenzMaxim 7:9cd16581b578 338 template <typename Allocator>
IanBenzMaxim 7:9cd16581b578 339 span(std::vector<value_type, Allocator> & vec)
IanBenzMaxim 7:9cd16581b578 340 : span_base(vec.empty() ? NULL : &vec.front()), size_(vec.size()) {}
IanBenzMaxim 7:9cd16581b578 341
IanBenzMaxim 7:9cd16581b578 342 template <typename Allocator>
IanBenzMaxim 7:9cd16581b578 343 span(const std::vector<value_type, Allocator> & vec)
IanBenzMaxim 7:9cd16581b578 344 : span_base(vec.empty() ? NULL : &vec.front()), size_(vec.size()) {}
IanBenzMaxim 7:9cd16581b578 345
IanBenzMaxim 7:9cd16581b578 346 template <typename Container>
IanBenzMaxim 8:5ea891c7d1a1 347 span(Container & cont,
IanBenzMaxim 8:5ea891c7d1a1 348 typename detail::enable_if_span_convertible<Container>::type * = NULL)
IanBenzMaxim 7:9cd16581b578 349 : span_base(cont.data()), size_(cont.size()) {}
IanBenzMaxim 7:9cd16581b578 350
IanBenzMaxim 7:9cd16581b578 351 template <typename Container>
IanBenzMaxim 8:5ea891c7d1a1 352 span(const Container & cont,
IanBenzMaxim 8:5ea891c7d1a1 353 typename detail::enable_if_span_convertible<const Container>::type * =
IanBenzMaxim 8:5ea891c7d1a1 354 NULL)
IanBenzMaxim 7:9cd16581b578 355 : span_base(cont.data()), size_(cont.size()) {}
IanBenzMaxim 7:9cd16581b578 356
IanBenzMaxim 7:9cd16581b578 357 /// @name Observers
IanBenzMaxim 7:9cd16581b578 358 /// @{
IanBenzMaxim 7:9cd16581b578 359
IanBenzMaxim 7:9cd16581b578 360 index_type size() const { return size_; }
IanBenzMaxim 7:9cd16581b578 361
IanBenzMaxim 7:9cd16581b578 362 index_type size_bytes() const { return size() * sizeof(element_type); }
IanBenzMaxim 7:9cd16581b578 363
IanBenzMaxim 7:9cd16581b578 364 bool empty() const { return size() == 0; }
IanBenzMaxim 7:9cd16581b578 365
IanBenzMaxim 7:9cd16581b578 366 /// @}
IanBenzMaxim 7:9cd16581b578 367
IanBenzMaxim 7:9cd16581b578 368 /// @name Subviews
IanBenzMaxim 7:9cd16581b578 369 /// @{
IanBenzMaxim 7:9cd16581b578 370
IanBenzMaxim 7:9cd16581b578 371 template <index_type Count> span<element_type, Count> last() const {
IanBenzMaxim 7:9cd16581b578 372 return span<element_type, Count>(this->data() + (size() - Count), Count);
IanBenzMaxim 7:9cd16581b578 373 }
IanBenzMaxim 7:9cd16581b578 374
IanBenzMaxim 7:9cd16581b578 375 /// @}
IanBenzMaxim 7:9cd16581b578 376
IanBenzMaxim 7:9cd16581b578 377 private:
IanBenzMaxim 7:9cd16581b578 378 index_type size_;
IanBenzMaxim 7:9cd16581b578 379 };
IanBenzMaxim 7:9cd16581b578 380
IanBenzMaxim 7:9cd16581b578 381 template <typename T>
IanBenzMaxim 7:9cd16581b578 382 span<T> make_span(T * data, typename span<T>::index_type size) {
IanBenzMaxim 7:9cd16581b578 383 return span<T>(data, size);
IanBenzMaxim 7:9cd16581b578 384 }
IanBenzMaxim 7:9cd16581b578 385
IanBenzMaxim 7:9cd16581b578 386 template <typename T> span<T> make_span(T * begin, T * end) {
IanBenzMaxim 7:9cd16581b578 387 return span<T>(begin, end);
IanBenzMaxim 7:9cd16581b578 388 }
IanBenzMaxim 7:9cd16581b578 389
IanBenzMaxim 7:9cd16581b578 390 template <typename T, size_t N> span<T, N> make_span(T (&arr)[N]) {
IanBenzMaxim 7:9cd16581b578 391 return span<T, N>(arr);
IanBenzMaxim 7:9cd16581b578 392 }
IanBenzMaxim 7:9cd16581b578 393
IanBenzMaxim 7:9cd16581b578 394 template <typename T, size_t N> span<T, N> make_span(array<T, N> & arr) {
IanBenzMaxim 7:9cd16581b578 395 return arr;
IanBenzMaxim 7:9cd16581b578 396 }
IanBenzMaxim 7:9cd16581b578 397
IanBenzMaxim 7:9cd16581b578 398 template <typename T, size_t N>
IanBenzMaxim 7:9cd16581b578 399 span<const T, N> make_span(const array<T, N> & arr) {
IanBenzMaxim 7:9cd16581b578 400 return arr;
IanBenzMaxim 7:9cd16581b578 401 }
IanBenzMaxim 7:9cd16581b578 402
IanBenzMaxim 7:9cd16581b578 403 template <typename Container>
IanBenzMaxim 7:9cd16581b578 404 span<typename Container::value_type> make_span(Container & cont) {
IanBenzMaxim 7:9cd16581b578 405 return cont;
IanBenzMaxim 7:9cd16581b578 406 }
IanBenzMaxim 7:9cd16581b578 407
IanBenzMaxim 7:9cd16581b578 408 template <typename Container>
IanBenzMaxim 7:9cd16581b578 409 span<const typename Container::value_type> make_span(const Container & cont) {
IanBenzMaxim 7:9cd16581b578 410 return cont;
IanBenzMaxim 7:9cd16581b578 411 }
IanBenzMaxim 7:9cd16581b578 412
IanBenzMaxim 7:9cd16581b578 413 } // namespace MaximInterfaceCore
IanBenzMaxim 7:9cd16581b578 414
IanBenzMaxim 7:9cd16581b578 415 #endif