/////////////////////////////////////////////////////////////////////////////// // // Copyright (c) 2015 Microsoft Corporation. All rights reserved. // // This code is licensed under the MIT License (MIT). // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /////////////////////////////////////////////////////////////////////////////// #include #include #include using namespace gsl; struct MyBase {}; struct MyDerived : public MyBase {}; struct Unrelated {}; // stand-in for a user-defined ref-counted class template struct RefCounted { RefCounted(T* p) : p_(p) {} operator T*() { return p_; } T* p_; }; SUITE(NotNullTests) { bool helper(not_null p) { return *p == 12; } TEST(TestNotNullConstructors) { #ifdef CONFIRM_COMPILATION_ERRORS not_null p = nullptr; // yay...does not compile! not_null*> p = 0; // yay...does not compile! not_null p; // yay...does not compile! std::unique_ptr up = std::make_unique(120); not_null p = up; // Forbid non-nullptr assignable types not_null> f(std::vector{1}); not_null z(10); not_null> y({1,2}); #endif int i = 12; auto rp = RefCounted(&i); not_null p(rp); CHECK(p.get() == &i); not_null> x(std::make_shared(10)); // shared_ptr is nullptr assignable } TEST(TestNotNullCasting) { MyBase base; MyDerived derived; Unrelated unrelated; not_null u = &unrelated; (void)u; not_null p = &derived; not_null q = &base; q = p; // allowed with heterogeneous copy ctor CHECK(q == p); #ifdef CONFIRM_COMPILATION_ERRORS q = u; // no viable conversion possible between MyBase* and Unrelated* p = q; // not possible to implicitly convert MyBase* to MyDerived* not_null r = p; not_null s = reinterpret_cast(p); #endif not_null t = reinterpret_cast(p.get()); CHECK(reinterpret_cast(p.get()) == reinterpret_cast(t.get())); } TEST(TestNotNullAssignment) { int i = 12; not_null p = &i; CHECK(helper(p)); int* q = nullptr; CHECK_THROW(p = q, fail_fast); } } int main(int, const char *[]) { return UnitTest::RunAllTests(); }