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 #include <UnitTest++/UnitTest++.h> 18 #include <gsl/gsl> 19 #include <vector> 20 21 using namespace gsl; 22 23 struct MyBase {}; 24 struct MyDerived : public MyBase {}; 25 struct Unrelated {}; 26 27 // stand-in for a user-defined ref-counted class 28 template<typename T> 29 struct RefCounted 30 { 31 RefCounted(T* p) : p_(p) {} 32 operator T*() { return p_; } 33 T* p_; 34 }; 35 36 SUITE(NotNullTests) 37 { 38 39 bool helper(not_null<int*> p) 40 { 41 return *p == 12; 42 } 43 44 TEST(TestNotNullConstructors) 45 { 46 #ifdef CONFIRM_COMPILATION_ERRORS 47 not_null<int*> p = nullptr; // yay...does not compile! 48 not_null<std::vector<char>*> p = 0; // yay...does not compile! 49 not_null<int*> p; // yay...does not compile! 50 std::unique_ptr<int> up = std::make_unique<int>(120); 51 not_null<int*> p = up; 52 53 // Forbid non-nullptr assignable types 54 not_null<std::vector<int>> f(std::vector<int>{1}); 55 not_null<int> z(10); 56 not_null<std::vector<int>> y({1,2}); 57 #endif 58 int i = 12; 59 auto rp = RefCounted<int>(&i); 60 not_null<int*> p(rp); 61 CHECK(p.get() == &i); 62 63 not_null<std::shared_ptr<int>> x(std::make_shared<int>(10)); // shared_ptr<int> is nullptr assignable 64 } 65 66 TEST(TestNotNullCasting) 67 { 68 MyBase base; 69 MyDerived derived; 70 Unrelated unrelated; 71 not_null<Unrelated*> u = &unrelated; 72 (void)u; 73 not_null<MyDerived*> p = &derived; 74 not_null<MyBase*> q = &base; 75 q = p; // allowed with heterogeneous copy ctor 76 CHECK(q == p); 77 78 #ifdef CONFIRM_COMPILATION_ERRORS 79 q = u; // no viable conversion possible between MyBase* and Unrelated* 80 p = q; // not possible to implicitly convert MyBase* to MyDerived* 81 82 not_null<Unrelated*> r = p; 83 not_null<Unrelated*> s = reinterpret_cast<Unrelated*>(p); 84 #endif 85 not_null<Unrelated*> t = reinterpret_cast<Unrelated*>(p.get()); 86 CHECK((void*)p.get() == (void*)t.get()); 87 } 88 89 TEST(TestNotNullAssignment) 90 { 91 int i = 12; 92 not_null<int*> p = &i; 93 CHECK(helper(p)); 94 95 int* q = nullptr; 96 CHECK_THROW(p = q, fail_fast); 97 } 98 } 99 100 int main(int, const char *[]) 101 { 102 return UnitTest::RunAllTests(); 103 } 104