• 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_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