1 /*------------------------------------------------------------------------- 2 * drawElements C++ Base Library 3 * ----------------------------- 4 * 5 * Copyright 2014 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief Unique pointer. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "deUniquePtr.hpp" 25 26 #include <exception> 27 28 namespace de 29 { 30 31 namespace 32 { 33 34 class Object 35 { 36 public: 37 Object (bool& exists) 38 : m_exists(exists) 39 { 40 m_exists = true; 41 } 42 43 ~Object (void) 44 { 45 m_exists = false; 46 } 47 48 private: 49 bool& m_exists; 50 }; 51 52 struct CustomDeleter 53 { 54 CustomDeleter (bool* called) : m_called(called) {} 55 56 void operator() (Object* ptr) 57 { 58 DE_TEST_ASSERT(!*m_called); 59 delete ptr; 60 *m_called = true; 61 } 62 63 bool* m_called; 64 }; 65 66 MovePtr<Object> createObject (bool& exists) 67 { 68 UniquePtr<Object> objectPtr(new Object(exists)); 69 return objectPtr.move(); 70 } 71 72 } // anonymous 73 74 void UniquePtr_selfTest (void) 75 { 76 // Basic test. 77 { 78 bool exists = false; 79 { 80 UniquePtr<Object> ptr(new Object(exists)); 81 DE_TEST_ASSERT(exists); 82 DE_TEST_ASSERT(ptr.get() != DE_NULL); 83 } 84 DE_TEST_ASSERT(!exists); 85 } 86 87 // Exception test. 88 { 89 bool exists = false; 90 try 91 { 92 UniquePtr<Object> ptr(new Object(exists)); 93 DE_TEST_ASSERT(exists); 94 DE_TEST_ASSERT(ptr.get() != DE_NULL); 95 throw std::exception(); 96 } 97 catch (const std::exception&) 98 { 99 DE_TEST_ASSERT(!exists); 100 } 101 DE_TEST_ASSERT(!exists); 102 } 103 104 // Expression test. 105 { 106 bool exists = false; 107 bool test = (UniquePtr<Object>(new Object(exists))).get() != DE_NULL && exists; 108 DE_TEST_ASSERT(!exists); 109 DE_TEST_ASSERT(test); 110 } 111 112 // Custom deleter. 113 { 114 bool exists = false; 115 bool deleterCalled = false; 116 { 117 UniquePtr<Object, CustomDeleter> ptr(new Object(exists), CustomDeleter(&deleterCalled)); 118 DE_TEST_ASSERT(exists); 119 DE_TEST_ASSERT(!deleterCalled); 120 DE_TEST_ASSERT(ptr.get() != DE_NULL); 121 } 122 DE_TEST_ASSERT(!exists); 123 DE_TEST_ASSERT(deleterCalled); 124 } 125 126 // MovePtr -> MovePtr moving 127 { 128 bool exists = false; 129 MovePtr<Object> ptr(new Object(exists)); 130 DE_TEST_ASSERT(exists); 131 { 132 MovePtr<Object> ptr2 = ptr; 133 DE_TEST_ASSERT(exists); 134 // Ownership moved to ptr2, should be deleted when ptr2 goes out of scope. 135 } 136 DE_TEST_ASSERT(!exists); 137 } 138 139 // UniquePtr -> MovePtr moving 140 { 141 bool exists = false; 142 UniquePtr<Object> ptr(new Object(exists)); 143 DE_TEST_ASSERT(exists); 144 { 145 MovePtr<Object> ptr2 = ptr.move(); 146 DE_TEST_ASSERT(exists); 147 // Ownership moved to ptr2, should be deleted when ptr2 goes out of scope. 148 } 149 DE_TEST_ASSERT(!exists); 150 } 151 152 // MovePtr -> UniquePtr moving 153 { 154 bool exists = false; 155 { 156 UniquePtr<Object> ptr(createObject(exists)); 157 DE_TEST_ASSERT(exists); 158 } 159 DE_TEST_ASSERT(!exists); 160 } 161 162 // MovePtr assignment 163 { 164 bool exists1 = false; 165 bool exists2 = false; 166 MovePtr<Object> ptr1(new Object(exists1)); 167 MovePtr<Object> ptr2(new Object(exists2)); 168 ptr1 = ptr2; 169 DE_TEST_ASSERT(!exists1); 170 DE_TEST_ASSERT(exists2); 171 } 172 173 // MovePtr stealing 174 { 175 bool exists = false; 176 Object* raw = DE_NULL; 177 { 178 MovePtr<Object> ptr1(new Object(exists)); 179 raw = ptr1.release(); 180 DE_TEST_ASSERT(raw != DE_NULL); 181 DE_TEST_ASSERT(ptr1.get() == DE_NULL); 182 DE_TEST_ASSERT(exists); 183 } 184 DE_TEST_ASSERT(exists); 185 delete raw; 186 DE_TEST_ASSERT(!exists); 187 } 188 189 // Null MovePtr and assigning to it. 190 { 191 bool exists = false; 192 { 193 MovePtr<Object> ptr1; 194 DE_TEST_ASSERT(ptr1.get() == DE_NULL); 195 MovePtr<Object> ptr2(new Object(exists)); 196 ptr1 = ptr2; 197 DE_TEST_ASSERT(exists); 198 DE_TEST_ASSERT(ptr1.get() != DE_NULL); 199 DE_TEST_ASSERT(ptr2.get() == DE_NULL); 200 } 201 DE_TEST_ASSERT(!exists); 202 } 203 204 #if 0 205 // UniquePtr assignment or copy construction should not compile. This 206 // piece of code is intentionally commented out. To manually test that 207 // copying a UniquePtr is statically forbidden, uncomment and try to 208 // compile. 209 { 210 bool exists = false; 211 UniquePtr<Object> ptr(new Object(exists)); 212 { 213 UniquePtr<Object> ptr2(ptr); 214 DE_TEST_ASSERT(exists); 215 } 216 DE_TEST_ASSERT(!exists); 217 } 218 #endif 219 } 220 221 } // de 222