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 21using namespace gsl; 22 23struct MyBase {}; 24struct MyDerived : public MyBase {}; 25struct Unrelated {}; 26 27// stand-in for a user-defined ref-counted class 28template<typename T> 29struct RefCounted 30{ 31 RefCounted(T* p) : p_(p) {} 32 operator T*() { return p_; } 33 T* p_; 34}; 35 36SUITE(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 100int main(int, const char *[]) 101{ 102 return UnitTest::RunAllTests(); 103} 104