Keir Mierle | 8ebb073 | 2012-04-30 23:09:08 -0700 | [diff] [blame] | 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 | |
| 42 | namespace ceres { |
| 43 | namespace internal { |
| 44 | |
| 45 | template <class C> class scoped_ptr; |
| 46 | template <class C, class Free> class scoped_ptr_malloc; |
| 47 | template <class C> class scoped_array; |
| 48 | |
| 49 | template <class C> |
| 50 | scoped_ptr<C> make_scoped_ptr(C *); |
| 51 | |
| 52 | // A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T> |
| 53 | // automatically deletes the pointer it holds (if any). That is, scoped_ptr<T> |
| 54 | // owns the T object that it points to. Like a T*, a scoped_ptr<T> may hold |
| 55 | // either NULL or a pointer to a T object. Also like T*, scoped_ptr<T> is |
| 56 | // thread-compatible, and once you dereference it, you get the threadsafety |
| 57 | // guarantees of T. |
| 58 | // |
| 59 | // The size of a scoped_ptr is small: sizeof(scoped_ptr<C>) == sizeof(C*) |
| 60 | template <class C> |
| 61 | class scoped_ptr { |
| 62 | public: |
| 63 | |
| 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 | |
| 197 | // The element type |
| 198 | typedef C element_type; |
| 199 | |
| 200 | // Constructor. Defaults to intializing with NULL. |
| 201 | // There is no way to create an uninitialized scoped_array. |
| 202 | // The input parameter must be allocated with new []. |
| 203 | explicit scoped_array(C* p = NULL) : array_(p) { } |
| 204 | |
| 205 | // Destructor. If there is a C object, delete it. |
| 206 | // We don't need to test ptr_ == NULL because C++ does that for us. |
| 207 | ~scoped_array() { |
| 208 | enum { type_must_be_complete = sizeof(C) }; |
| 209 | delete[] array_; |
| 210 | } |
| 211 | |
| 212 | // Reset. Deletes the current owned object, if any. |
| 213 | // Then takes ownership of a new object, if given. |
| 214 | // this->reset(this->get()) works. |
| 215 | void reset(C* p = NULL) { |
| 216 | if (p != array_) { |
| 217 | enum { type_must_be_complete = sizeof(C) }; |
| 218 | delete[] array_; |
| 219 | array_ = p; |
| 220 | } |
| 221 | } |
| 222 | |
| 223 | // Get one element of the current object. |
| 224 | // Will assert() if there is no current object, or index i is negative. |
| 225 | C& operator[](std::ptrdiff_t i) const { |
| 226 | assert(i >= 0); |
| 227 | assert(array_ != NULL); |
| 228 | return array_[i]; |
| 229 | } |
| 230 | |
| 231 | // Get a pointer to the zeroth element of the current object. |
| 232 | // If there is no current object, return NULL. |
| 233 | C* get() const { |
| 234 | return array_; |
| 235 | } |
| 236 | |
| 237 | // Comparison operators. |
| 238 | // These return whether a scoped_array and a raw pointer refer to |
| 239 | // the same array, not just to two different but equal arrays. |
| 240 | bool operator==(const C* p) const { return array_ == p; } |
| 241 | bool operator!=(const C* p) const { return array_ != p; } |
| 242 | |
| 243 | // Swap two scoped arrays. |
| 244 | void swap(scoped_array& p2) { |
| 245 | C* tmp = array_; |
| 246 | array_ = p2.array_; |
| 247 | p2.array_ = tmp; |
| 248 | } |
| 249 | |
| 250 | // Release an array. |
| 251 | // The return value is the current pointer held by this object. |
| 252 | // If this object holds a NULL pointer, the return value is NULL. |
| 253 | // After this operation, this object will hold a NULL pointer, |
| 254 | // and will not own the object any more. |
| 255 | C* release() { |
| 256 | C* retVal = array_; |
| 257 | array_ = NULL; |
| 258 | return retVal; |
| 259 | } |
| 260 | |
| 261 | private: |
| 262 | C* array_; |
| 263 | |
| 264 | // Forbid comparison of different scoped_array types. |
| 265 | template <class C2> bool operator==(scoped_array<C2> const& p2) const; |
| 266 | template <class C2> bool operator!=(scoped_array<C2> const& p2) const; |
| 267 | |
| 268 | // Disallow evil constructors |
| 269 | scoped_array(const scoped_array&); |
| 270 | void operator=(const scoped_array&); |
| 271 | }; |
| 272 | |
| 273 | // Free functions |
| 274 | template <class C> |
| 275 | inline void swap(scoped_array<C>& p1, scoped_array<C>& p2) { |
| 276 | p1.swap(p2); |
| 277 | } |
| 278 | |
| 279 | template <class C> |
| 280 | inline bool operator==(const C* p1, const scoped_array<C>& p2) { |
| 281 | return p1 == p2.get(); |
| 282 | } |
| 283 | |
| 284 | template <class C> |
| 285 | inline bool operator==(const C* p1, const scoped_array<const C>& p2) { |
| 286 | return p1 == p2.get(); |
| 287 | } |
| 288 | |
| 289 | template <class C> |
| 290 | inline bool operator!=(const C* p1, const scoped_array<C>& p2) { |
| 291 | return p1 != p2.get(); |
| 292 | } |
| 293 | |
| 294 | template <class C> |
| 295 | inline bool operator!=(const C* p1, const scoped_array<const C>& p2) { |
| 296 | return p1 != p2.get(); |
| 297 | } |
| 298 | |
| 299 | // This class wraps the c library function free() in a class that can be |
| 300 | // passed as a template argument to scoped_ptr_malloc below. |
| 301 | class ScopedPtrMallocFree { |
| 302 | public: |
| 303 | inline void operator()(void* x) const { |
| 304 | free(x); |
| 305 | } |
| 306 | }; |
| 307 | |
| 308 | } // namespace internal |
| 309 | } // namespace ceres |
| 310 | |
| 311 | #endif // CERES_PUBLIC_INTERNAL_SCOPED_PTR_H_ |