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_THROW...
24
25 #include <gsl/gsl_util> // for at
26
27 #include <array> // for array
28 #include <cstddef> // for size_t
29 #include <initializer_list> // for initializer_list
30 #include <vector> // for vector
31
32
33 namespace gsl {
34 struct fail_fast;
35 } // namespace gsl
36
37 using gsl::fail_fast;
38
39 GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
40 GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
41 TEST_CASE("static_array")
42 {
43 int a[4] = {1, 2, 3, 4};
44 const int(&c_a)[4] = a;
45
46 for (int i = 0; i < 4; ++i) {
47 CHECK(&gsl::at(a, i) == &a[i]);
48 CHECK(&gsl::at(c_a, i) == &a[i]);
49 }
50
51 CHECK_THROWS_AS(gsl::at(a, -1), fail_fast);
52 CHECK_THROWS_AS(gsl::at(a, 4), fail_fast);
53 CHECK_THROWS_AS(gsl::at(c_a, -1), fail_fast);
54 CHECK_THROWS_AS(gsl::at(c_a, 4), fail_fast);
55 }
56
57 GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
58 GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
59 TEST_CASE("std_array")
60 {
61 std::array<int, 4> a = {1, 2, 3, 4};
62 const std::array<int, 4>& c_a = a;
63
64 for (int i = 0; i < 4; ++i) {
65 CHECK(&gsl::at(a, i) == &a[static_cast<std::size_t>(i)]);
66 CHECK(&gsl::at(c_a, i) == &a[static_cast<std::size_t>(i)]);
67 }
68
69 CHECK_THROWS_AS(gsl::at(a, -1), fail_fast);
70 CHECK_THROWS_AS(gsl::at(a, 4), fail_fast);
71 CHECK_THROWS_AS(gsl::at(c_a, -1), fail_fast);
72 CHECK_THROWS_AS(gsl::at(c_a, 4), fail_fast);
73 }
74
75 GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
76 GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
77 TEST_CASE("StdVector")
78 {
79 std::vector<int> a = {1, 2, 3, 4};
80 const std::vector<int>& c_a = a;
81
82 for (int i = 0; i < 4; ++i) {
83 CHECK(&gsl::at(a, i) == &a[static_cast<std::size_t>(i)]);
84 CHECK(&gsl::at(c_a, i) == &a[static_cast<std::size_t>(i)]);
85 }
86
87 CHECK_THROWS_AS(gsl::at(a, -1), fail_fast);
88 CHECK_THROWS_AS(gsl::at(a, 4), fail_fast);
89 CHECK_THROWS_AS(gsl::at(c_a, -1), fail_fast);
90 CHECK_THROWS_AS(gsl::at(c_a, 4), fail_fast);
91 }
92
93 GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
94 GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
95 TEST_CASE("InitializerList")
96 {
97 const std::initializer_list<int> a = {1, 2, 3, 4};
98
99 for (int i = 0; i < 4; ++i) {
100 CHECK(gsl::at(a, i) == i + 1);
101 CHECK(gsl::at({1, 2, 3, 4}, i) == i + 1);
102 }
103
104 CHECK_THROWS_AS(gsl::at(a, -1), fail_fast);
105 CHECK_THROWS_AS(gsl::at(a, 4), fail_fast);
106 CHECK_THROWS_AS(gsl::at({1, 2, 3, 4}, -1), fail_fast);
107 CHECK_THROWS_AS(gsl::at({1, 2, 3, 4}, 4), fail_fast);
108 }
109
110 #if !defined(_MSC_VER) || defined(__clang__) || _MSC_VER >= 1910
111 GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
112 GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
113 GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
test_constexpr()114 static constexpr bool test_constexpr()
115 {
116 int a1[4] = {1, 2, 3, 4};
117 const int(&c_a1)[4] = a1;
118 std::array<int, 4> a2 = {1, 2, 3, 4};
119 const std::array<int, 4>& c_a2 = a2;
120
121 for (int i = 0; i < 4; ++i) {
122 if (&gsl::at(a1, i) != &a1[i]) return false;
123 if (&gsl::at(c_a1, i) != &a1[i]) return false;
124 // requires C++17:
125 // if (&gsl::at(a2, i) != &a2[static_cast<std::size_t>(i)]) return false;
126 if (&gsl::at(c_a2, i) != &c_a2[static_cast<std::size_t>(i)]) return false;
127 if (gsl::at({1, 2, 3, 4}, i) != i + 1) return false;
128 }
129
130 return true;
131 }
132
133 static_assert(test_constexpr(), "FAIL");
134 #endif
135
136