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: Object(bool & exists)37 Object(bool &exists) : m_exists(exists) 38 { 39 m_exists = true; 40 } 41 ~Object(void)42 ~Object(void) 43 { 44 m_exists = false; 45 } 46 47 private: 48 bool &m_exists; 49 }; 50 51 struct CustomDeleter 52 { CustomDeleterde::__anon90d808610111::CustomDeleter53 CustomDeleter(bool *called) : m_called(called) 54 { 55 } 56 operator ()de::__anon90d808610111::CustomDeleter57 void operator()(Object *ptr) 58 { 59 DE_TEST_ASSERT(!*m_called); 60 delete ptr; 61 *m_called = true; 62 } 63 64 bool *m_called; 65 }; 66 createObject(bool & exists)67MovePtr<Object> createObject(bool &exists) 68 { 69 UniquePtr<Object> objectPtr(new Object(exists)); 70 return objectPtr.move(); 71 } 72 73 } // namespace 74 UniquePtr_selfTest(void)75void UniquePtr_selfTest(void) 76 { 77 // Basic test. 78 { 79 bool exists = false; 80 { 81 UniquePtr<Object> ptr(new Object(exists)); 82 DE_TEST_ASSERT(exists); 83 DE_TEST_ASSERT(ptr.get() != DE_NULL); 84 } 85 DE_TEST_ASSERT(!exists); 86 } 87 88 // Exception test. 89 { 90 bool exists = false; 91 try 92 { 93 UniquePtr<Object> ptr(new Object(exists)); 94 DE_TEST_ASSERT(exists); 95 DE_TEST_ASSERT(ptr.get() != DE_NULL); 96 throw std::exception(); 97 } 98 catch (const std::exception &) 99 { 100 DE_TEST_ASSERT(!exists); 101 } 102 DE_TEST_ASSERT(!exists); 103 } 104 105 // Expression test. 106 { 107 bool exists = false; 108 bool test = (UniquePtr<Object>(new Object(exists))).get() != DE_NULL && exists; 109 DE_TEST_ASSERT(!exists); 110 DE_TEST_ASSERT(test); 111 } 112 113 // Custom deleter. 114 { 115 bool exists = false; 116 bool deleterCalled = false; 117 { 118 UniquePtr<Object, CustomDeleter> ptr(new Object(exists), CustomDeleter(&deleterCalled)); 119 DE_TEST_ASSERT(exists); 120 DE_TEST_ASSERT(!deleterCalled); 121 DE_TEST_ASSERT(ptr.get() != DE_NULL); 122 } 123 DE_TEST_ASSERT(!exists); 124 DE_TEST_ASSERT(deleterCalled); 125 } 126 127 // MovePtr -> MovePtr moving 128 { 129 bool exists = false; 130 MovePtr<Object> ptr(new Object(exists)); 131 DE_TEST_ASSERT(exists); 132 { 133 MovePtr<Object> ptr2 = ptr; 134 DE_TEST_ASSERT(exists); 135 // Ownership moved to ptr2, should be deleted when ptr2 goes out of scope. 136 } 137 DE_TEST_ASSERT(!exists); 138 } 139 140 // UniquePtr -> MovePtr moving 141 { 142 bool exists = false; 143 UniquePtr<Object> ptr(new Object(exists)); 144 DE_TEST_ASSERT(exists); 145 { 146 MovePtr<Object> ptr2 = ptr.move(); 147 DE_TEST_ASSERT(exists); 148 // Ownership moved to ptr2, should be deleted when ptr2 goes out of scope. 149 } 150 DE_TEST_ASSERT(!exists); 151 } 152 153 // MovePtr -> UniquePtr moving 154 { 155 bool exists = false; 156 { 157 UniquePtr<Object> ptr(createObject(exists)); 158 DE_TEST_ASSERT(exists); 159 } 160 DE_TEST_ASSERT(!exists); 161 } 162 163 // MovePtr assignment 164 { 165 bool exists1 = false; 166 bool exists2 = false; 167 MovePtr<Object> ptr1(new Object(exists1)); 168 MovePtr<Object> ptr2(new Object(exists2)); 169 ptr1 = ptr2; 170 DE_TEST_ASSERT(!exists1); 171 DE_TEST_ASSERT(exists2); 172 } 173 174 // MovePtr stealing 175 { 176 bool exists = false; 177 Object *raw = DE_NULL; 178 { 179 MovePtr<Object> ptr1(new Object(exists)); 180 raw = ptr1.release(); 181 DE_TEST_ASSERT(raw != DE_NULL); 182 DE_TEST_ASSERT(ptr1.get() == DE_NULL); 183 DE_TEST_ASSERT(exists); 184 } 185 DE_TEST_ASSERT(exists); 186 delete raw; 187 DE_TEST_ASSERT(!exists); 188 } 189 190 // Null MovePtr and assigning to it. 191 { 192 bool exists = false; 193 { 194 MovePtr<Object> ptr1; 195 DE_TEST_ASSERT(ptr1.get() == DE_NULL); 196 MovePtr<Object> ptr2(new Object(exists)); 197 ptr1 = ptr2; 198 DE_TEST_ASSERT(exists); 199 DE_TEST_ASSERT(ptr1.get() != DE_NULL); 200 DE_TEST_ASSERT(ptr2.get() == DE_NULL); 201 } 202 DE_TEST_ASSERT(!exists); 203 } 204 205 #if 0 206 // UniquePtr assignment or copy construction should not compile. This 207 // piece of code is intentionally commented out. To manually test that 208 // copying a UniquePtr is statically forbidden, uncomment and try to 209 // compile. 210 { 211 bool exists = false; 212 UniquePtr<Object> ptr(new Object(exists)); 213 { 214 UniquePtr<Object> ptr2(ptr); 215 DE_TEST_ASSERT(exists); 216 } 217 DE_TEST_ASSERT(!exists); 218 } 219 #endif 220 } 221 222 } // namespace de 223