blob: b8c1196e728281a295664cc51842ddd0e7c0bac9 [file] [log] [blame]
Neil MacIntoshcec26a22016-02-24 11:26:28 -08001///////////////////////////////////////////////////////////////////////////////
2//
3// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
4//
5// This code is licensed under the MIT License (MIT).
6//
7// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
10// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
12// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
13// THE SOFTWARE.
14//
15///////////////////////////////////////////////////////////////////////////////
16
17#pragma once
18
19#ifndef GSL_SPAN_H
20#define GSL_SPAN_H
21
22#include "gsl_assert.h"
23#include "gsl_util.h"
Neil MacIntoshcec26a22016-02-24 11:26:28 -080024#include <array>
Neil MacIntoshcec26a22016-02-24 11:26:28 -080025#include <limits>
Neil MacIntoshd3929c52016-02-24 16:11:33 -080026#include <iterator>
Neil MacIntoshcec26a22016-02-24 11:26:28 -080027#include <stdexcept>
28#include <type_traits>
29#include <utility>
30
31#ifdef _MSC_VER
32
33// turn off some warnings that are noisy about our Expects statements
34#pragma warning(push)
35#pragma warning(disable : 4127) // conditional expression is constant
36
37// No MSVC does constexpr fully yet
38#pragma push_macro("constexpr")
39#define constexpr
40
41// VS 2013 workarounds
42#if _MSC_VER <= 1800
43
44#define GSL_MSVC_HAS_VARIADIC_CTOR_BUG
45#define GSL_MSVC_NO_SUPPORT_FOR_MOVE_CTOR_DEFAULT
46
47// noexcept is not understood
48#ifndef GSL_THROW_ON_CONTRACT_VIOLATION
49#pragma push_macro("noexcept")
50#define noexcept /* nothing */
51#endif
52
53// turn off some misguided warnings
54#pragma warning(push)
55#pragma warning(disable : 4351) // warns about newly introduced aggregate initializer behavior
56#pragma warning(disable : 4512) // warns that assignment op could not be generated
57
58#endif // _MSC_VER <= 1800
59
60#endif // _MSC_VER
61
62#ifdef GSL_THROW_ON_CONTRACT_VIOLATION
63
64#ifdef _MSC_VER
65#pragma push_macro("noexcept")
66#endif
67
68#define noexcept /* nothing */
69
70#endif // GSL_THROW_ON_CONTRACT_VIOLATION
71
72namespace gsl
73{
74
Neil MacIntoshd3929c52016-02-24 16:11:33 -080075// [views.constants], constants
76constexpr const std::ptrdiff_t dynamic_extent = -1;
77
78
79// [span], class template span
80template <class ElementType, std::ptrdiff_t Extent = dynamic_extent>
81class span {
82public:
83 // constants and types
84 using element_type = ElementType;
85 using index_type = std::ptrdiff_t;
86 using pointer = element_type*;
87 using reference = element_type&;
88#if 0 // TODO
89 using iterator = /*implementation-defined */;
90 using const_iterator = /* implementation-defined */;
91 using reverse_iterator = std::reverse_iterator<iterator>;
92 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
93#endif
94 constexpr static const index_type extent = Extent;
95
96 // [span.cons], span constructors, copy, assignment, and destructor
97 constexpr span() noexcept : data_(nullptr), size_(0)
98 { static_assert(extent == dynamic_extent || extent == 0, "Cannot default initialize a fixed-length span."); }
99 constexpr span(nullptr_t) noexcept : span() {}
100 constexpr span(pointer ptr, index_type count) : data_(ptr), size_(count)
101 { Expects((!ptr && count == 0) || (ptr && count >= 0)); }
102#if 0 // TODO
103 constexpr span(pointer firstElem, pointer lastElem);
104 template <size_t N>
105 constexpr span(element_type(&arr)[N]);
106 template <size_t N>
107 constexpr span(array<remove_const_t<element_type>, N>& arr);
108 template <size_t N>
109 constexpr span(const array<remove_const_t<element_type>, N>& arr);
110 template <class Container>
111 constexpr span(Container& cont);
112 template <class Container>
113 span(const Container&&) = delete;
114 constexpr span(const span& other) noexcept = default;
115 constexpr span(span&& other) noexcept = default;
116 template <class OtherElementType, ptrdiff_t OtherExtent>
117 constexpr span(const span<OtherElementType, OtherExtent>& other);
118 template <class OtherElementType, ptrdiff_t OtherExtent>
119 constexpr span(span<OtherElementType, OtherExtent>&& other);
120 ~span() noexcept = default;
121 constexpr span& operator=(const span& other) noexcept = default;
122 constexpr span& operator=(span&& other) noexcept = default;
123
124 // [span.sub], span subviews
125 template <ptrdiff_t Count>
126 constexpr span<element_type, Count> first() const;
127 template <ptrdiff_t Count>
128 constexpr span<element_type, Count> last() const;
129 template <ptrdiff_t Offset, ptrdiff_t Count = dynamic_extent>
130 constexpr span<element_type, Count> subspan() const;
131 constexpr span<element_type, dynamic_extent> first(index_type count) const;
132 constexpr span<element_type, dynamic_extent> last(index_type count) const;
133 constexpr span<element_type, dynamic_extent> subspan(index_type offset, index_type count = dynamic_extent) const;
134#endif
135 // [span.obs], span observers
136 constexpr index_type length() const noexcept { return size(); }
137 constexpr index_type size() const noexcept { return size_; }
138 constexpr index_type length_bytes() const noexcept { return size_bytes(); }
139 constexpr index_type size_bytes() const noexcept { return size() * sizeof(element_type); }
140 constexpr bool empty() const noexcept { return size() == 0; }
141
142#if 0 // TODO
143 // [span.elem], span element access
144 constexpr reference operator[](index_type idx) const;
145 constexpr reference operator()(index_type idx) const;
146#endif
147 constexpr pointer data() const noexcept { return data_; }
148#if 0 // TODO
149 // [span.iter], span iterator support
150 iterator begin() const noexcept;
151 iterator end() const noexcept;
152
153 const_iterator cbegin() const noexcept;
154 const_iterator cend() const noexcept;
155
156 reverse_iterator rbegin() const noexcept;
157 reverse_iterator rend() const noexcept;
158
159 const_reverse_iterator crbegin() const noexcept;
160 const_reverse_iterator crend() const noexcept;
161#endif
162private:
163 pointer data_;
164 index_type size_;
165};
166
167
168#if 0 // TODO
169// [span.comparison], span comparison operators
170template <class ElementType, ptrdiff_t Extent>
171constexpr bool operator==(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r) const noexcept;
172
173template <class ElementType, ptrdiff_t Extent>
174constexpr bool operator!=(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r) const noexcept;
175
176template <class ElementType, ptrdiff_t Extent>
177constexpr bool operator<(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r) const noexcept;
178
179template <class ElementType, ptrdiff_t Extent>
180constexpr bool operator<=(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r) const noexcept;
181
182template <class ElementType, ptrdiff_t Extent>
183constexpr bool operator>(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r) const noexcept;
184
185template <class ElementType, ptrdiff_t Extent>
186constexpr bool operator>=(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r) const noexcept;
187#endif
188
189
190#if 0 // TODO
191// [span.objectrep], views of object representation
192template <class ElementType, ptrdiff_t Extent>
193constexpr span<const char, ((Extent == dynamic_extent) ? dynamic_extent : (sizeof(ElementType) * Extent))> as_bytes(span<ElementType, Extent> s) noexcept;
194
195template <class ElementType, ptrdiff_t Extent>
196constexpr span<char, ((Extent == dynamic_extent) ? dynamic_extent : (sizeof(ElementType) * Extent))> as_writeable_bytes(span<ElementType, Extent>) noexcept;
197#endif
Neil MacIntoshcec26a22016-02-24 11:26:28 -0800198
199} // namespace gsl
200
201#ifdef _MSC_VER
202
203#undef constexpr
204#pragma pop_macro("constexpr")
205
206#if _MSC_VER <= 1800
207#pragma warning(pop)
208
209#ifndef GSL_THROW_ON_CONTRACT_VIOLATION
210#undef noexcept
211#pragma pop_macro("noexcept")
212#endif // GSL_THROW_ON_CONTRACT_VIOLATION
213
214#undef GSL_MSVC_HAS_VARIADIC_CTOR_BUG
215
216#endif // _MSC_VER <= 1800
217
218#endif // _MSC_VER
219
220#if defined(GSL_THROW_ON_CONTRACT_VIOLATION)
221
222#undef noexcept
223
224#ifdef _MSC_VER
225#pragma warning(pop)
226#pragma pop_macro("noexcept")
227#endif
228
229#endif // GSL_THROW_ON_CONTRACT_VIOLATION
230
231#endif // GSL_SPAN_H