• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 ///////////////////////////////////////////////////////////////////////////////
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 #ifdef _MSC_VER
18 // blanket turn off warnings from CppCoreCheck from catch
19 // so people aren't annoyed by them when running the tool.
20 #pragma warning(disable : 26440 26426) // from catch
21 #endif
22 
23 #include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, CHE...
24 
25 #include <gsl/gsl_algorithm> // for copy
26 #include <gsl/span>          // for span
27 
28 #include <array>   // for array
29 #include <cstddef> // for size_t
30 
31 namespace gsl {
32 struct fail_fast;
33 }  // namespace gsl
34 
35 using namespace std;
36 using namespace gsl;
37 
38 GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
39 GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
40 TEST_CASE("same_type")
41 {
42     // dynamic source and destination span
43     {
44         std::array<int, 5> src{1, 2, 3, 4, 5};
45         std::array<int, 10> dst{};
46 
47         const span<int> src_span(src);
48         const span<int> dst_span(dst);
49 
50         copy(src_span, dst_span);
51         copy(src_span, dst_span.subspan(src_span.size()));
52 
53         for (std::size_t i = 0; i < src.size(); ++i) {
54             CHECK(dst[i] == src[i]);
55             CHECK(dst[i + src.size()] == src[i]);
56         }
57     }
58 
59     // static source and dynamic destination span
60     {
61         std::array<int, 5> src{1, 2, 3, 4, 5};
62         std::array<int, 10> dst{};
63 
64         const span<int, 5> src_span(src);
65         const span<int> dst_span(dst);
66 
67         copy(src_span, dst_span);
68         copy(src_span, dst_span.subspan(src_span.size()));
69 
70         for (std::size_t i = 0; i < src.size(); ++i) {
71             CHECK(dst[i] == src[i]);
72             CHECK(dst[i + src.size()] == src[i]);
73         }
74     }
75 
76     // dynamic source and static destination span
77     {
78         std::array<int, 5> src{1, 2, 3, 4, 5};
79         std::array<int, 10> dst{};
80 
81         const span<int> src_span(src);
82         const span<int, 10> dst_span(dst);
83 
84         copy(src_span, dst_span);
85         copy(src_span, dst_span.subspan(src_span.size()));
86 
87         for (std::size_t i = 0; i < src.size(); ++i) {
88             CHECK(dst[i] == src[i]);
89             CHECK(dst[i + src.size()] == src[i]);
90         }
91     }
92 
93     // static source and destination span
94     {
95         std::array<int, 5> src{1, 2, 3, 4, 5};
96         std::array<int, 10> dst{};
97 
98         const span<int, 5> src_span(src);
99         const span<int, 10> dst_span(dst);
100 
101         copy(src_span, dst_span);
102         copy(src_span, dst_span.subspan(src_span.size()));
103 
104         for (std::size_t i = 0; i < src.size(); ++i) {
105             CHECK(dst[i] == src[i]);
106             CHECK(dst[i + src.size()] == src[i]);
107         }
108     }
109 }
110 
111 
112 GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
113 GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
114 TEST_CASE("compatible_type")
115 {
116     // dynamic source and destination span
117     {
118         std::array<short, 5> src{1, 2, 3, 4, 5};
119         std::array<int, 10> dst{};
120 
121         const span<short> src_span(src);
122         const span<int> dst_span(dst);
123 
124         copy(src_span, dst_span);
125         copy(src_span, dst_span.subspan(src_span.size()));
126 
127         for (std::size_t i = 0; i < src.size(); ++i) {
128             CHECK(dst[i] == src[i]);
129             CHECK(dst[i + src.size()] == src[i]);
130         }
131     }
132 
133     // static source and dynamic destination span
134     {
135         std::array<short, 5> src{1, 2, 3, 4, 5};
136         std::array<int, 10> dst{};
137 
138         const span<short, 5> src_span(src);
139         const span<int> dst_span(dst);
140 
141         copy(src_span, dst_span);
142         copy(src_span, dst_span.subspan(src_span.size()));
143 
144         for (std::size_t i = 0; i < src.size(); ++i) {
145             CHECK(dst[i] == src[i]);
146             CHECK(dst[i + src.size()] == src[i]);
147         }
148     }
149 
150     // dynamic source and static destination span
151     {
152         std::array<short, 5> src{1, 2, 3, 4, 5};
153         std::array<int, 10> dst{};
154 
155         const span<short> src_span(src);
156         const span<int, 10> dst_span(dst);
157 
158         copy(src_span, dst_span);
159         copy(src_span, dst_span.subspan(src_span.size()));
160 
161         for (std::size_t i = 0; i < src.size(); ++i) {
162             CHECK(dst[i] == src[i]);
163             CHECK(dst[i + src.size()] == src[i]);
164         }
165     }
166 
167     // static source and destination span
168     {
169         std::array<short, 5> src{1, 2, 3, 4, 5};
170         std::array<int, 10> dst{};
171 
172         const span<short, 5> src_span(src);
173         const span<int, 10> dst_span(dst);
174 
175         copy(src_span, dst_span);
176         copy(src_span, dst_span.subspan(src_span.size()));
177 
178         for (std::size_t i = 0; i < src.size(); ++i) {
179             CHECK(dst[i] == src[i]);
180             CHECK(dst[i + src.size()] == src[i]);
181         }
182     }
183 }
184 
185 #ifdef CONFIRM_COMPILATION_ERRORS
186 TEST_CASE("incompatible_type")
187 {
188     std::array<int, 4> src{1, 2, 3, 4};
189     std::array<int*, 12> dst{};
190 
191     span<int> src_span_dyn(src);
192     span<int, 4> src_span_static(src);
193     span<int*> dst_span_dyn(dst);
194     span<int*, 4> dst_span_static(dst);
195 
196     // every line should produce a compilation error
197     copy(src_span_dyn, dst_span_dyn);
198     copy(src_span_dyn, dst_span_static);
199     copy(src_span_static, dst_span_dyn);
200     copy(src_span_static, dst_span_static);
201 }
202 #endif
203 
204 TEST_CASE("small_destination_span")
205 {
206     std::array<int, 12> src{1, 2, 3, 4};
207     std::array<int, 4> dst{};
208 
209     const span<int> src_span_dyn(src);
210     const span<int, 12> src_span_static(src);
211     const span<int> dst_span_dyn(dst);
212     const span<int, 4> dst_span_static(dst);
213 
214     CHECK_THROWS_AS(copy(src_span_dyn, dst_span_dyn), fail_fast);
215     CHECK_THROWS_AS(copy(src_span_dyn, dst_span_static), fail_fast);
216     CHECK_THROWS_AS(copy(src_span_static, dst_span_dyn), fail_fast);
217 
218 #ifdef CONFIRM_COMPILATION_ERRORS
219     copy(src_span_static, dst_span_static);
220 #endif
221 }
222