mirror of
https://gitcode.com/gh_mirrors/ope/OpenFace.git
synced 2026-05-15 19:57:53 +00:00
226 lines
5.1 KiB
C++
226 lines
5.1 KiB
C++
// Copyright (C) 2007 Davis E. King (davis@dlib.net)
|
|
// License: Boost Software License See LICENSE.txt for the full license.
|
|
#ifndef DLIB_WEAK_PTr_
|
|
#define DLIB_WEAK_PTr_
|
|
|
|
#include <algorithm>
|
|
#include <memory>
|
|
#include "shared_ptr.h"
|
|
#include "../algs.h"
|
|
#include "weak_ptr_abstract.h"
|
|
|
|
namespace dlib {
|
|
|
|
template <
|
|
typename T
|
|
>
|
|
class weak_ptr
|
|
{
|
|
|
|
/*!
|
|
CONVENTION
|
|
- if (weak_node != 0) then
|
|
- data == valid pointer to shared data
|
|
- weak_node->ref_count == the number of weak_ptrs that reference this->data
|
|
- else
|
|
- data == 0
|
|
|
|
- expired() == ((weak_node == 0) || (weak_node->shared_node == 0))
|
|
- if (expired() == false) then
|
|
- use_count() == weak_node->shared_node->ref_count
|
|
- else
|
|
- use_count() == 0
|
|
!*/
|
|
|
|
public:
|
|
typedef T element_type;
|
|
|
|
weak_ptr(
|
|
) : data(0), weak_node(0)
|
|
{
|
|
}
|
|
|
|
template<typename Y>
|
|
weak_ptr(
|
|
const shared_ptr<Y>& r
|
|
)
|
|
{
|
|
data = r.data;
|
|
if (r.shared_node)
|
|
{
|
|
if (r.shared_node->weak_node)
|
|
{
|
|
weak_node = r.shared_node->weak_node;
|
|
weak_node->ref_count += 1;
|
|
}
|
|
else
|
|
{
|
|
weak_node = new weak_ptr_node(r.shared_node);
|
|
r.shared_node->weak_node = weak_node;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
weak_node = 0;
|
|
}
|
|
}
|
|
|
|
weak_ptr(
|
|
const weak_ptr& r
|
|
)
|
|
{
|
|
data = r.data;
|
|
weak_node = r.weak_node;
|
|
if (weak_node)
|
|
weak_node->ref_count += 1;
|
|
}
|
|
|
|
template<typename Y>
|
|
weak_ptr(
|
|
const weak_ptr<Y>& r
|
|
)
|
|
{
|
|
data = r.data;
|
|
weak_node = r.weak_node;
|
|
if (weak_node)
|
|
weak_node->ref_count += 1;
|
|
}
|
|
|
|
~weak_ptr(
|
|
)
|
|
{
|
|
if (weak_node)
|
|
{
|
|
// make note that this weak_ptr is being destroyed
|
|
weak_node->ref_count -= 1;
|
|
|
|
// if this is the last weak_ptr then we should clean up our stuff
|
|
if (weak_node->ref_count == 0)
|
|
{
|
|
if (expired() == false)
|
|
weak_node->shared_node->weak_node = 0;
|
|
delete weak_node;
|
|
}
|
|
}
|
|
}
|
|
|
|
weak_ptr& operator= (
|
|
const weak_ptr& r
|
|
)
|
|
{
|
|
weak_ptr(r).swap(*this);
|
|
return *this;
|
|
}
|
|
|
|
template<typename Y>
|
|
weak_ptr& operator= (
|
|
const weak_ptr<Y>& r
|
|
)
|
|
{
|
|
weak_ptr(r).swap(*this);
|
|
return *this;
|
|
}
|
|
|
|
template<typename Y>
|
|
weak_ptr& operator=(
|
|
const shared_ptr<Y>& r
|
|
)
|
|
{
|
|
weak_ptr(r).swap(*this);
|
|
return *this;
|
|
}
|
|
|
|
long use_count(
|
|
) const
|
|
{
|
|
if (expired())
|
|
return 0;
|
|
else
|
|
return weak_node->shared_node->ref_count;
|
|
}
|
|
|
|
bool expired() const { return weak_node == 0 || weak_node->shared_node == 0; }
|
|
|
|
shared_ptr<T> lock(
|
|
) const
|
|
{
|
|
if (expired())
|
|
return shared_ptr<T>();
|
|
else
|
|
return shared_ptr<T>(*this);
|
|
}
|
|
|
|
void reset(
|
|
)
|
|
{
|
|
weak_ptr().swap(*this);
|
|
}
|
|
|
|
void swap(
|
|
weak_ptr<T>& b
|
|
)
|
|
{
|
|
std::swap(data, b.data);
|
|
std::swap(weak_node, b.weak_node);
|
|
}
|
|
|
|
template <typename Y>
|
|
bool _private_less (
|
|
const weak_ptr<Y>& rhs
|
|
) const
|
|
{
|
|
if (expired())
|
|
{
|
|
if (rhs.expired())
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (rhs.expired())
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
// in this case they have both not expired so lets
|
|
// compare the shared_node pointers
|
|
return (weak_node->shared_node) < (rhs.weak_node->shared_node);
|
|
}
|
|
}
|
|
}
|
|
|
|
private:
|
|
|
|
template <typename Y> friend class shared_ptr;
|
|
template <typename Y> friend class weak_ptr;
|
|
|
|
T* data;
|
|
weak_ptr_node* weak_node;
|
|
};
|
|
|
|
template<typename T, typename U>
|
|
bool operator< (
|
|
const weak_ptr<T>& a,
|
|
const weak_ptr<U>& b
|
|
)
|
|
{
|
|
return a._private_less(b);
|
|
}
|
|
|
|
template<typename T>
|
|
void swap(
|
|
weak_ptr<T>& a,
|
|
weak_ptr<T> & b
|
|
) { a.swap(b); }
|
|
}
|
|
|
|
#endif // DLIB_WEAK_PTr_
|
|
|
|
|