/*****************************************************************************/
// Copyright 2006 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_auto_ptr.h#2 $ */
/* $DateTime: 2012/07/11 10:36:56 $ */
/* $Change: 838485 $ */
/* $Author: tknoll $ */
/** \file
* Class to implement std::auto_ptr like functionality even on platforms which do not
* have a full Standard C++ library.
*/
/*****************************************************************************/
#ifndef __dng_auto_ptr__
#define __dng_auto_ptr__
#include "dng_memory.h"
#include <memory>
#include <stddef.h>
#include <stdlib.h>
/*****************************************************************************/
// The following template has similar functionality to the STL auto_ptr, without
// requiring all the weight of STL.
/*****************************************************************************/
/// \brief A class intended to be used in stack scope to hold a pointer from new. The
/// held pointer will be deleted automatically if the scope is left without calling
/// Release on the AutoPtr first.
template<class T>
class AutoPtr
{
private:
T *p_;
public:
/// Construct an AutoPtr with no referent.
AutoPtr () : p_ (0) { }
/// Construct an AutoPtr which owns the argument pointer.
/// \param p pointer which constructed AutoPtr takes ownership of. p will be
/// deleted on destruction or Reset unless Release is called first.
explicit AutoPtr (T *p) : p_( p ) { }
/// Reset is called on destruction.
~AutoPtr ();
/// Call Reset with a pointer from new. Uses T's default constructor.
void Alloc ();
/// Return the owned pointer of this AutoPtr, NULL if none. No change in
/// ownership or other effects occur.
T *Get () const { return p_; }
/// Return the owned pointer of this AutoPtr, NULL if none. The AutoPtr gives
/// up ownership and takes NULL as its value.
T *Release ();
/// If a pointer is owned, it is deleted. Ownership is taken of passed in
/// pointer.
/// \param p pointer which constructed AutoPtr takes ownership of. p will be
/// deleted on destruction or Reset unless Release is called first.
void Reset (T *p);
/// If a pointer is owned, it is deleted and the AutoPtr takes NULL as its
/// value.
void Reset ();
/// Allows members of the owned pointer to be accessed directly. It is an
/// error to call this if the AutoPtr has NULL as its value.
T *operator-> () const { return p_; }
/// Returns a reference to the object that the owned pointer points to. It is
/// an error to call this if the AutoPtr has NULL as its value.
T &operator* () const { return *p_; }
/// Swap with another auto ptr.
friend inline void Swap (AutoPtr< T > &x, AutoPtr< T > &y)
{
T* temp = x.p_;
x.p_ = y.p_;
y.p_ = temp;
}
private:
// Hidden copy constructor and assignment operator. I don't think the STL
// "feature" of grabbing ownership of the pointer is a good idea.
AutoPtr (AutoPtr<T> &rhs);
AutoPtr<T> & operator= (AutoPtr<T> &rhs);
};
/*****************************************************************************/
template<class T>
AutoPtr<T>::~AutoPtr ()
{
delete p_;
p_ = 0;
}
/*****************************************************************************/
template<class T>
T *AutoPtr<T>::Release ()
{
T *result = p_;
p_ = 0;
return result;
}
/*****************************************************************************/
template<class T>
void AutoPtr<T>::Reset (T *p)
{
if (p_ != p)
{
if (p_ != 0)
delete p_;
p_ = p;
}
}
/*****************************************************************************/
template<class T>
void AutoPtr<T>::Reset ()
{
if (p_ != 0)
{
delete p_;
p_ = 0;
}
}
/*****************************************************************************/
template<class T>
void AutoPtr<T>::Alloc ()
{
this->Reset (new T);
}
/*****************************************************************************/
/// \brief A class that provides a variable-length array that automatically
/// deletes the underlying memory on scope exit.
///
/// T is not required to be movable. The class is implemented using
/// dng_std_vector but purposely does not use any member functions that require
/// T to be movable.
template<typename T>
class AutoArray
{
public:
/// Construct an AutoArray that refers to a null pointer.
AutoArray () { }
/// Construct an AutoArray containing 'count' elements, which are
/// default-constructed. If an out-of-memory condition occurs, a
/// dng_exception with error code dng_error_memory is thrown.
explicit AutoArray (size_t count)
: vector_(new dng_std_vector<T>(count))
{
}
/// Changes the size of the AutoArray to 'count' elements. The new
/// elements are default-constructed. The previously existing elements
/// of the array are destroyed. If an out-of-memory condition occurs, a
/// dng_exception with error code dng_error_memory is thrown.
void Reset (size_t count)
{
vector_.reset(new dng_std_vector<T>(count));
}
/// Allows indexing into the AutoArray. The index 'i' must be
/// non-negative and smaller than size of the array (the value that was
/// passed to the constructor or to Reset()).
T &operator[] (ptrdiff_t i)
{
return (*vector_) [i];
}
const T &operator[] (ptrdiff_t i) const
{
return (*vector_) [i];
}
/// Return a pointer to the beginning of the array.
T *Get ()
{
if (vector_)
return vector_->data();
else
return nullptr;
}
const T *Get () const
{
if (vector_)
return vector_->data();
else
return nullptr;
}
private:
// Hidden copy constructor and assignment operator.
AutoArray (const AutoArray &);
const AutoArray & operator= (const AutoArray &);
private:
std::unique_ptr<dng_std_vector<T> > vector_;
};
/*****************************************************************************/
#endif
/*****************************************************************************/