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