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
22 // Fix VS2015 build breaks in Release
23 #pragma warning(disable : 4702) // unreachable code
24 #endif
25
26 #include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, TEST_...
27 #include <gsl/pointers> // for not_null, operator<, operator<=, operator>
28
29 namespace gsl
30 {
31 struct fail_fast;
32 } // namespace gsl
33
34 using namespace gsl;
35
36 GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
helper(not_null<int * > p)37 bool helper(not_null<int*> p) { return *p == 12; }
38 GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
helper_const(not_null<const int * > p)39 bool helper_const(not_null<const int*> p) { return *p == 12; }
40
41 GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
strict_helper(strict_not_null<int * > p)42 bool strict_helper(strict_not_null<int*> p) { return *p == 12; }
43 GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
strict_helper_const(strict_not_null<const int * > p)44 bool strict_helper_const(strict_not_null<const int*> p) { return *p == 12; }
45
return_pointer()46 int* return_pointer() { return nullptr; }
return_pointer_const()47 const int* return_pointer_const() { return nullptr; }
48
49 GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
50 TEST_CASE("TestStrictNotNull")
51 {
52 {
53 // raw ptr <-> strict_not_null
54 int x = 42;
55
56 #ifdef CONFIRM_COMPILATION_ERRORS
57 strict_not_null<int*> snn = &x;
58 strict_helper(&x);
59 strict_helper_const(&x);
60 strict_helper(return_pointer());
61 strict_helper_const(return_pointer_const());
62 #endif
63
64 const strict_not_null<int*> snn1{&x};
65
66 helper(snn1);
67 helper_const(snn1);
68
69 CHECK(*snn1 == 42);
70 }
71
72 {
73 // strict_not_null -> strict_not_null
74 int x = 42;
75
76 strict_not_null<int*> snn1{&x};
77 const strict_not_null<int*> snn2{&x};
78
79 strict_helper(snn1);
80 strict_helper_const(snn1);
81 strict_helper_const(snn2);
82
83 CHECK(snn1 == snn2);
84 }
85
86 {
87 // strict_not_null -> not_null
88 int x = 42;
89
90 strict_not_null<int*> snn{&x};
91
92 const not_null<int*> nn1 = snn;
93 const not_null<int*> nn2{snn};
94
95 helper(snn);
96 helper_const(snn);
97
98 CHECK(snn == nn1);
99 CHECK(snn == nn2);
100 }
101
102 {
103 // not_null -> strict_not_null
104 int x = 42;
105
106 not_null<int*> nn{&x};
107
108 const strict_not_null<int*> snn1{nn};
109 const strict_not_null<int*> snn2{nn};
110
111 strict_helper(nn);
112 strict_helper_const(nn);
113
114 CHECK(snn1 == nn);
115 CHECK(snn2 == nn);
116
117 std::hash<strict_not_null<int*>> hash_snn;
118 std::hash<not_null<int*>> hash_nn;
119
120 CHECK(hash_nn(snn1) == hash_nn(nn));
121 CHECK(hash_snn(snn1) == hash_nn(nn));
122 CHECK(hash_nn(snn1) == hash_nn(snn2));
123 CHECK(hash_snn(snn1) == hash_snn(nn));
124 }
125
126 #ifdef CONFIRM_COMPILATION_ERRORS
127 {
128 strict_not_null<int*> p{nullptr};
129 }
130 #endif
131 }
132
133 #if defined(__cplusplus) && (__cplusplus >= 201703L)
134
135 GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
136 TEST_CASE("TestStrictNotNullConstructorTypeDeduction")
137 {
138 {
139 int i = 42;
140
141 strict_not_null x{&i};
142 helper(strict_not_null{&i});
143 helper_const(strict_not_null{&i});
144
145 CHECK(*x == 42);
146 }
147
148 {
149 int i = 42;
150 int* p = &i;
151
152 strict_not_null x{p};
153 helper(strict_not_null{p});
154 helper_const(strict_not_null{p});
155
156 CHECK(*x == 42);
157 }
158
159 {
__anonccf8307b0102() 160 auto workaround_macro = []() {
161 int* p1 = nullptr;
162 const strict_not_null x{p1};
163 };
164 CHECK_THROWS_AS(workaround_macro(), fail_fast);
165 }
166
167 {
__anonccf8307b0202() 168 auto workaround_macro = []() {
169 const int* p1 = nullptr;
170 const strict_not_null x{p1};
171 };
172 CHECK_THROWS_AS(workaround_macro(), fail_fast);
173 }
174
175 {
176 int* p = nullptr;
177
178 CHECK_THROWS_AS(helper(strict_not_null{p}), fail_fast);
179 CHECK_THROWS_AS(helper_const(strict_not_null{p}), fail_fast);
180 }
181
182 #ifdef CONFIRM_COMPILATION_ERRORS
183 {
184 strict_not_null x{nullptr};
185 helper(strict_not_null{nullptr});
186 helper_const(strict_not_null{nullptr});
187 }
188 #endif
189 }
190 #endif // #if defined(__cplusplus) && (__cplusplus >= 201703L)
191
192 static_assert(std::is_nothrow_move_constructible<strict_not_null<void*>>::value,
193 "strict_not_null must be no-throw move constructible");
194