1 // Ceres Solver - A fast non-linear least squares minimizer 2 // Copyright 2010, 2011, 2012 Google Inc. All rights reserved. 3 // http://code.google.com/p/ceres-solver/ 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are met: 7 // 8 // * Redistributions of source code must retain the above copyright notice, 9 // this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above copyright notice, 11 // this list of conditions and the following disclaimer in the documentation 12 // and/or other materials provided with the distribution. 13 // * Neither the name of Google Inc. nor the names of its contributors may be 14 // used to endorse or promote products derived from this software without 15 // specific prior written permission. 16 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 // POSSIBILITY OF SUCH DAMAGE. 28 // 29 // Author: jorg (at) google.com (Jorg Brown) 30 // 31 // This is an implementation designed to match the anticipated future TR2 32 // implementation of the scoped_ptr class, and its closely-related brethren, 33 // scoped_array, scoped_ptr_malloc, and make_scoped_ptr. 34 35 #ifndef CERES_PUBLIC_INTERNAL_SCOPED_PTR_H_ 36 #define CERES_PUBLIC_INTERNAL_SCOPED_PTR_H_ 37 38 #include <assert.h> 39 #include <stdlib.h> 40 #include <cstddef> 41 #include <algorithm> 42 43 namespace ceres { 44 namespace internal { 45 46 template <class C> class scoped_ptr; 47 template <class C, class Free> class scoped_ptr_malloc; 48 template <class C> class scoped_array; 49 50 template <class C> 51 scoped_ptr<C> make_scoped_ptr(C *); 52 53 // A scoped_ptr<T> is like a T*, except that the destructor of 54 // scoped_ptr<T> automatically deletes the pointer it holds (if 55 // any). That is, scoped_ptr<T> owns the T object that it points 56 // to. Like a T*, a scoped_ptr<T> may hold either NULL or a pointer to 57 // a T object. Also like T*, scoped_ptr<T> is thread-compatible, and 58 // once you dereference it, you get the threadsafety guarantees of T. 59 // 60 // The size of a scoped_ptr is small: sizeof(scoped_ptr<C>) == sizeof(C*) 61 template <class C> 62 class scoped_ptr { 63 public: 64 // The element type 65 typedef C element_type; 66 67 // Constructor. Defaults to intializing with NULL. 68 // There is no way to create an uninitialized scoped_ptr. 69 // The input parameter must be allocated with new. 70 explicit scoped_ptr(C* p = NULL) : ptr_(p) { } 71 72 // Destructor. If there is a C object, delete it. 73 // We don't need to test ptr_ == NULL because C++ does that for us. 74 ~scoped_ptr() { 75 enum { type_must_be_complete = sizeof(C) }; 76 delete ptr_; 77 } 78 79 // Reset. Deletes the current owned object, if any. 80 // Then takes ownership of a new object, if given. 81 // this->reset(this->get()) works. 82 void reset(C* p = NULL) { 83 if (p != ptr_) { 84 enum { type_must_be_complete = sizeof(C) }; 85 delete ptr_; 86 ptr_ = p; 87 } 88 } 89 90 // Accessors to get the owned object. 91 // operator* and operator-> will assert() if there is no current object. 92 C& operator*() const { 93 assert(ptr_ != NULL); 94 return *ptr_; 95 } 96 C* operator->() const { 97 assert(ptr_ != NULL); 98 return ptr_; 99 } 100 C* get() const { return ptr_; } 101 102 // Comparison operators. 103 // These return whether a scoped_ptr and a raw pointer refer to 104 // the same object, not just to two different but equal objects. 105 bool operator==(const C* p) const { return ptr_ == p; } 106 bool operator!=(const C* p) const { return ptr_ != p; } 107 108 // Swap two scoped pointers. 109 void swap(scoped_ptr& p2) { 110 C* tmp = ptr_; 111 ptr_ = p2.ptr_; 112 p2.ptr_ = tmp; 113 } 114 115 // Release a pointer. 116 // The return value is the current pointer held by this object. 117 // If this object holds a NULL pointer, the return value is NULL. 118 // After this operation, this object will hold a NULL pointer, 119 // and will not own the object any more. 120 C* release() { 121 C* retVal = ptr_; 122 ptr_ = NULL; 123 return retVal; 124 } 125 126 private: 127 C* ptr_; 128 129 // google3 friend class that can access copy ctor (although if it actually 130 // calls a copy ctor, there will be a problem) see below 131 friend scoped_ptr<C> make_scoped_ptr<C>(C *p); 132 133 // Forbid comparison of scoped_ptr types. If C2 != C, it totally doesn't 134 // make sense, and if C2 == C, it still doesn't make sense because you should 135 // never have the same object owned by two different scoped_ptrs. 136 template <class C2> bool operator==(scoped_ptr<C2> const& p2) const; 137 template <class C2> bool operator!=(scoped_ptr<C2> const& p2) const; 138 139 // Disallow evil constructors 140 scoped_ptr(const scoped_ptr&); 141 void operator=(const scoped_ptr&); 142 }; 143 144 // Free functions 145 template <class C> 146 inline void swap(scoped_ptr<C>& p1, scoped_ptr<C>& p2) { 147 p1.swap(p2); 148 } 149 150 template <class C> 151 inline bool operator==(const C* p1, const scoped_ptr<C>& p2) { 152 return p1 == p2.get(); 153 } 154 155 template <class C> 156 inline bool operator==(const C* p1, const scoped_ptr<const C>& p2) { 157 return p1 == p2.get(); 158 } 159 160 template <class C> 161 inline bool operator!=(const C* p1, const scoped_ptr<C>& p2) { 162 return p1 != p2.get(); 163 } 164 165 template <class C> 166 inline bool operator!=(const C* p1, const scoped_ptr<const C>& p2) { 167 return p1 != p2.get(); 168 } 169 170 template <class C> 171 scoped_ptr<C> make_scoped_ptr(C *p) { 172 // This does nothing but to return a scoped_ptr of the type that the passed 173 // pointer is of. (This eliminates the need to specify the name of T when 174 // making a scoped_ptr that is used anonymously/temporarily.) From an 175 // access control point of view, we construct an unnamed scoped_ptr here 176 // which we return and thus copy-construct. Hence, we need to have access 177 // to scoped_ptr::scoped_ptr(scoped_ptr const &). However, it is guaranteed 178 // that we never actually call the copy constructor, which is a good thing 179 // as we would call the temporary's object destructor (and thus delete p) 180 // if we actually did copy some object, here. 181 return scoped_ptr<C>(p); 182 } 183 184 // scoped_array<C> is like scoped_ptr<C>, except that the caller must allocate 185 // with new [] and the destructor deletes objects with delete []. 186 // 187 // As with scoped_ptr<C>, a scoped_array<C> either points to an object 188 // or is NULL. A scoped_array<C> owns the object that it points to. 189 // scoped_array<T> is thread-compatible, and once you index into it, 190 // the returned objects have only the threadsafety guarantees of T. 191 // 192 // Size: sizeof(scoped_array<C>) == sizeof(C*) 193 template <class C> 194 class scoped_array { 195 public: 196 // The element type 197 typedef C element_type; 198 199 // Constructor. Defaults to intializing with NULL. 200 // There is no way to create an uninitialized scoped_array. 201 // The input parameter must be allocated with new []. 202 explicit scoped_array(C* p = NULL) : array_(p) { } 203 204 // Destructor. If there is a C object, delete it. 205 // We don't need to test ptr_ == NULL because C++ does that for us. 206 ~scoped_array() { 207 enum { type_must_be_complete = sizeof(C) }; 208 delete[] array_; 209 } 210 211 // Reset. Deletes the current owned object, if any. 212 // Then takes ownership of a new object, if given. 213 // this->reset(this->get()) works. 214 void reset(C* p = NULL) { 215 if (p != array_) { 216 enum { type_must_be_complete = sizeof(C) }; 217 delete[] array_; 218 array_ = p; 219 } 220 } 221 222 // Get one element of the current object. 223 // Will assert() if there is no current object, or index i is negative. 224 C& operator[](std::ptrdiff_t i) const { 225 assert(i >= 0); 226 assert(array_ != NULL); 227 return array_[i]; 228 } 229 230 // Get a pointer to the zeroth element of the current object. 231 // If there is no current object, return NULL. 232 C* get() const { 233 return array_; 234 } 235 236 // Comparison operators. 237 // These return whether a scoped_array and a raw pointer refer to 238 // the same array, not just to two different but equal arrays. 239 bool operator==(const C* p) const { return array_ == p; } 240 bool operator!=(const C* p) const { return array_ != p; } 241 242 // Swap two scoped arrays. 243 void swap(scoped_array& p2) { 244 C* tmp = array_; 245 array_ = p2.array_; 246 p2.array_ = tmp; 247 } 248 249 // Release an array. 250 // The return value is the current pointer held by this object. 251 // If this object holds a NULL pointer, the return value is NULL. 252 // After this operation, this object will hold a NULL pointer, 253 // and will not own the object any more. 254 C* release() { 255 C* retVal = array_; 256 array_ = NULL; 257 return retVal; 258 } 259 260 private: 261 C* array_; 262 263 // Forbid comparison of different scoped_array types. 264 template <class C2> bool operator==(scoped_array<C2> const& p2) const; 265 template <class C2> bool operator!=(scoped_array<C2> const& p2) const; 266 267 // Disallow evil constructors 268 scoped_array(const scoped_array&); 269 void operator=(const scoped_array&); 270 }; 271 272 // Free functions 273 template <class C> 274 inline void swap(scoped_array<C>& p1, scoped_array<C>& p2) { 275 p1.swap(p2); 276 } 277 278 template <class C> 279 inline bool operator==(const C* p1, const scoped_array<C>& p2) { 280 return p1 == p2.get(); 281 } 282 283 template <class C> 284 inline bool operator==(const C* p1, const scoped_array<const C>& p2) { 285 return p1 == p2.get(); 286 } 287 288 template <class C> 289 inline bool operator!=(const C* p1, const scoped_array<C>& p2) { 290 return p1 != p2.get(); 291 } 292 293 template <class C> 294 inline bool operator!=(const C* p1, const scoped_array<const C>& p2) { 295 return p1 != p2.get(); 296 } 297 298 // This class wraps the c library function free() in a class that can be 299 // passed as a template argument to scoped_ptr_malloc below. 300 class ScopedPtrMallocFree { 301 public: 302 inline void operator()(void* x) const { 303 free(x); 304 } 305 }; 306 307 } // namespace internal 308 } // namespace ceres 309 310 #endif // CERES_PUBLIC_INTERNAL_SCOPED_PTR_H_ 311