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@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 43namespace ceres { 44namespace internal { 45 46template <class C> class scoped_ptr; 47template <class C, class Free> class scoped_ptr_malloc; 48template <class C> class scoped_array; 49 50template <class C> 51scoped_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*) 61template <class C> 62class 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 145template <class C> 146inline void swap(scoped_ptr<C>& p1, scoped_ptr<C>& p2) { 147 p1.swap(p2); 148} 149 150template <class C> 151inline bool operator==(const C* p1, const scoped_ptr<C>& p2) { 152 return p1 == p2.get(); 153} 154 155template <class C> 156inline bool operator==(const C* p1, const scoped_ptr<const C>& p2) { 157 return p1 == p2.get(); 158} 159 160template <class C> 161inline bool operator!=(const C* p1, const scoped_ptr<C>& p2) { 162 return p1 != p2.get(); 163} 164 165template <class C> 166inline bool operator!=(const C* p1, const scoped_ptr<const C>& p2) { 167 return p1 != p2.get(); 168} 169 170template <class C> 171scoped_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*) 193template <class C> 194class 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 273template <class C> 274inline void swap(scoped_array<C>& p1, scoped_array<C>& p2) { 275 p1.swap(p2); 276} 277 278template <class C> 279inline bool operator==(const C* p1, const scoped_array<C>& p2) { 280 return p1 == p2.get(); 281} 282 283template <class C> 284inline bool operator==(const C* p1, const scoped_array<const C>& p2) { 285 return p1 == p2.get(); 286} 287 288template <class C> 289inline bool operator!=(const C* p1, const scoped_array<C>& p2) { 290 return p1 != p2.get(); 291} 292 293template <class C> 294inline 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. 300class 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