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