📄 smart_ptr.hpp
字号:
#ifndef smart_ptr_HPP_HEADER_GUARD_
#define smart_ptr_HPP_HEADER_GUARD_
/*
For more details, which include example usage, full introduction, parameters, and tutorial,
see following link:
http://axter.com/smartptr
SET A SIDE NOTES:
For ease of testing and distribution, all the policies are included in the same header with the smart_ptr.
Once testing is near completion, the policies will be moved to separate header, and the smart_ptr header
will have an #include to the new policy headers.
This source file is documented in a Doxygen friendly format.
This format allows Doxygen to pull the comments out, and to create help
documents in HTML, RTF, man, and XML formats.
http://www.stack.nl/~dimitri/doxygen/index.html
*/
/*!
@mainpage smart_ptr (Policy Based Smart Pointer)
@author David Maisonave (Axter) (609-345-1007) (<A HREF="http://www.axter.com" TARGET="_top">www.axter.com</A>)\n
Copyright (C) 2006\n
\n
@section Contents
\ref DownloadSourceCode\n
\ref LastRevisionNumberDate\n
\ref SmartPtrLicense\n
\ref Why_Use_smart_ptr\n
\ref Policy_Classes\n
\ref Multithreading\n
\ref smart_ptr_Members\n
\ref Motivation\n
@section Introduction Introduction
smart_ptr is a smart pointer policy class that can use different
ownership logic and semantic polices, which allows the developer to
get the best performance and/or interface for a particular requirement.
It has synchronization logic which allows it to be used in a \ref Multithreading
environment.
The smart_ptr class can be used with STL containers to create containers
of smart pointers, moreover it can be used to create a container of
abstract based objects via smart_ptr.
In general, smart_ptr is faster than boost::shared_ptr. When used
with STL containers, the smart pointer is faster than the boost
pointer containers. More importantly, the interface for an STL container
of smart_ptr is a 100% compatible with STL containers, which is not the
case with the boost pointer containers.\n
smart_ptr has a policy that allows it to synchronize access to both
the smart pointer and the pointee. This allows both the smart_ptr and the pointee
to safely be used in a multithreading environment.\n
The smart_ptr has been compiled and tested on VC++ 6.0, 7.1, 8.0, GNU 3.x,
Borland 5.5, and Comeau 4.3.\n
\n
This help document includes three other smart pointers.\n
cow_ptr\n
copy_ptr\n
sync_ptr\n
These three smart pointers are not part of the smart_ptr class, but because
much of smart_ptr's implementation derived from these three classes, they're
included in the help document as a base of reference. They're also used
in the unit testing as a base line comparison, and to insure that the
smart_ptr policies are not effecting performance.\n
For more information about other types of smart pointers,
see \ref Other_Smart_Pointers
\n
@section example_usage Example Usage
@include ../examples/example_smart_ptr_usage.cpp
\n
@section LastRevisionNumberDate Revision
\verbatim
$Date: 3/23/06 3:48a $
$Revision: 8 $
\endverbatim
To view revison history, see \ref Revision_History
@section DownloadSourceCode Download
Download smart pointer source code using following link:\n
http://axter.com/smartptr/smartptr.zip
\n
Note: All the smart pointers listed in this document are
implemented using *.hpp files. There's no object files,
*.cpp files, or DLL/SO files. To use the smart pointers
in your project, just add an include.
\verbatim
#include "smart_ptr.hpp"
\endverbatim
\n\n
Windows users can optionally use (CHM) help file, which
can be downloaded through the following link:\n
http://axter.com/smartptr/smartptr_chm.zip\n
*/
#ifndef __BORLANDC__
#if !defined(_MSC_VER) || (_MSC_VER > 1200)
//Both VC++6.0 and borland compilers don't support type defined via policy
#define SMART_PTR_SUPPORT_RETURN_TYPE_THROUGH_POLICY_
#endif
#endif
/*!
@struct allocator_default_policy
@brief This is the Default allocator policy for smart_ptr.
This policy does NOT require that the target class have a clone function or clone
logic.
Cloning is performed by using the type pass to the constructor.
In order to use this policy, the target type must be pass to the constructor.
\n
<b>Example Usage</b>
@include ../examples/example_allocator_policy_usage.hxx
\n
@note
This policy can detect slicing better than the clone_function_allocator_policy,
but not as well as the clone_static_function_allocator_policy.
allocator_default_policy can detect slicing at runtime through constructor.
This policy is more generic than clone_function_allocator_policy and
clone_static_function_allocator_policy, because it does not require the
target class to have any type of clone function.
@see smart_ptr, clone_function_allocator_policy,
clone_static_function_allocator_policy
*/
struct allocator_default_policy
{
/*!
@brief allocate clones the input argument by calling the type copy constructor.
@pre Requires type to have a copy constructor,
and pointee to be same type as pointer
@warning @image html warning.gif
Requires correct type for proper cloning
@param[in] ptr valid pointer or NULL
@return A new object, or NULL if input parameter is NULL
*/
template<typename T_obj> static inline T_obj* allocate(const T_obj* ptr)
{
if (ptr) return new T_obj(*ptr);
return NULL;
}
/*!
@param[in] ptr valid pointer or NULL
*/
template<typename T_obj> static inline void deallocate(T_obj* ptr){delete ptr;}
};
/*!
@struct clone_function_allocator_policy
@brief This is an allocator policy that uses traditional cloning method.
This policy requires that the target class have a virtual clone function.
The normal usage is to create a base class with a pure virtual clone function,
and have each derived class implement the clone function. This includes
derived derived classes, and so-on.
\n
<b>Example Usage</b>
@include ../examples/example_clone_function_allocator_policy_usage.hxx
\n
@note
This policy is least capable of detecting slicing. Slicing can only be detected
on runtime when cloning is performed. This policy also requires more
maintenance, because each derived class has to implement the cloning function.
Because of this cloning function requirement, this policy is less generic than
the allocator_default_policy
@see smart_ptr, allocator_default_policy,
clone_static_function_allocator_policy
*/
struct clone_function_allocator_policy
{
/*!
@brief allocate clones the input argument by calling virtual function do_clone.
@pre Base type requires do_clone virtual function, and pointee type requires
do_clone implementation
@warning @image html warning.gif
slicing can occur if derived derived type fails to implement do_clone
@param[in] ptr valid pointer or NULL
@return A new object, or NULL if input parameter is NULL
*/
template<typename T_obj> static inline T_obj* allocate(const T_obj* ptr)
{
if(!ptr) return NULL;
return static_cast<T_obj*>(ptr->do_clone());
}
/*!
@param[in] ptr valid pointer or NULL
*/
template<typename T_obj> static inline void deallocate(T_obj* ptr){delete ptr;}
};
/*! @struct clone_static_function_allocator_policy
@brief This is an allocator policy that uses a static cloning method.
This policy requires that the target class have a static clone function.
Each derived class must implement the static clone function.
This includes derived derived classes, and so-on.
\n
<b>Example Usage</b>
@include ../examples/example_clone_static_function_allocator_policy_usage.hxx
\n
@note
This policy is able to avoid slicing better, because is can detect
slicing at compile time.
This policy requires about the same amount of maintenance as the
clone_function_allocator_policy, but more maintenance than the
allocator_default_policy, because each derived class
has to implement the static cloning function.
Because of this cloning function requirement, this policy is less generic than
the allocator_default_policy
@see smart_ptr, allocator_default_policy, clone_function_allocator_policy,
allocator_array_policy
*/
struct clone_static_function_allocator_policy
{
/*!
@brief allocate clones the input argument by calling static function do_clone.
@pre Target type requires static do_clone function
@param[in] ptr valid pointer or NULL
@return A new object, or NULL if input parameter is NULL
*/
template<typename T_obj> static inline T_obj* allocate(const T_obj* ptr)
{
if(!ptr) return NULL;
return T_obj::do_clone(*ptr);
}
/*!
@param[in] ptr valid pointer or NULL
*/
template<typename T_obj> static inline void deallocate(T_obj* ptr){delete ptr;}
};
// @cond INCLUDE_ALL_OBJS_
/*! @struct allocator_array_policy
@brief This is an allocator policy which creates an array of objects.
The current implementation of this policy is only practical in shared type
ownership logic, or static size array. If a dynamic interchangeable array is
needed, than a vector type should be used instead (smart_ptr<vector<T>,
shared_ptr_policy<ref_link_policy> >
@warning @image html warning.gif
Due to the limitations of this policy, it may not make it through peer review
@see smart_ptr, allocator_default_policy, clone_function_allocator_policy,
clone_static_function_allocator_policy
*/
template<size_t size_array>
struct allocator_array_policy
{
/*!
@brief allocate clones an array.
@pre input argument must be pointing to an array equal to size_array
@warning @image html warning.gif
The allocate for this policy needs some work, to make it dynamic
@param[in] ptr valid pointer or NULL
@return A new array of objects, or NULL if input parameter is NULL
*/
template<typename T_obj> static T_obj* allocate(const T_obj* ptr)
{
if (!ptr) return NULL;
#ifdef BOOST_ASSERT
BOOST_ASSERT(size_array);
#endif //BOOST_ASSERT
T_obj *arr = new T_obj[size_array];
for(size_t i = 0;i < size_array;++i)
arr[i] = ptr[i];
return arr;
}
/*!
@param[in] ptr valid pointer or NULL
*/
template<typename T_obj> static inline void deallocate(T_obj* ptr){delete[] ptr;}
};
// @endcond
/*! @struct value_comparsion_semantic_policy
@brief This makes smart_ptr compare the pointee instead of the pointer address.
This is a policy that allows smart_ptr to be used with associated containers,
and STL sorting algorithms.
When used with comparison operators, this policy makes
smart_ptr compare the pointee, instead of the pointer address.
\n
<b>Example Usage</b>
@include ../examples/example_value_comparsion_semantic_policy_usage.hxx
\n
@note All members are static template functions, so as to avoid
requiring the class to be a template class, and to avoid requiring
an instance of the class.
@see smart_ptr, pointer_comparsion_semantic_policy, no_comparsion_semantic_policy
*/
struct value_comparsion_semantic_policy
{
template<class T1, class T2> static bool less_than(const T1 & a, const T2 & b){return (*a.c_ptr()) < (*b.c_ptr());}
template<class T1, class T2> static bool greater_than(const T1 & a, const T2 & b){return (*a.c_ptr()) > (*b.c_ptr());}
template<class T1, class T2> static bool less_than_or_equal(const T1 & a, const T2 & b){return (*a.c_ptr()) <= (*b.c_ptr());}
template<class T1, class T2> static bool greater_than_or_equal(const T1 & a, const T2 & b){return (*a.c_ptr()) >= (*b.c_ptr());}
template<class T1, class T2> static bool is_equal(const T1 & a, const T2 & b){return (*a.c_ptr()) == (*b.c_ptr());}
};
/*! @struct pointer_comparsion_semantic_policy
@brief This makes smart_ptr compare the pointer address.
This policy gives the smart_ptr class normal pointer semantics when use with
comparison operators. Comparison operators compare pointer address instead of
pointee object. This may be desirable when using generic smart pointer coding,
in which smart_ptr needs to work the same as other smart pointers.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -