mirror of
https://gitcode.com/gh_mirrors/ope/OpenFace.git
synced 2026-07-12 08:07:49 +00:00
Master commit of OpenFace.
This commit is contained in:
217
lib/3rdParty/dlib/include/dlib/smart_pointers/scoped_ptr.h
vendored
Normal file
217
lib/3rdParty/dlib/include/dlib/smart_pointers/scoped_ptr.h
vendored
Normal file
@@ -0,0 +1,217 @@
|
||||
// Copyright (C) 2007 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_SCOPED_PTr_
|
||||
#define DLIB_SCOPED_PTr_
|
||||
|
||||
#include <algorithm>
|
||||
#include "../noncopyable.h"
|
||||
#include "../algs.h"
|
||||
#include "scoped_ptr_abstract.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <typename T>
|
||||
struct default_deleter
|
||||
{
|
||||
void operator() (T* item) const
|
||||
{
|
||||
delete item;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct default_deleter<T[]>
|
||||
{
|
||||
void operator() (T* item) const
|
||||
{
|
||||
delete [] item;
|
||||
}
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename deleter = default_deleter<T>
|
||||
>
|
||||
class scoped_ptr : noncopyable
|
||||
{
|
||||
/*!
|
||||
CONVENTION
|
||||
- get() == ptr
|
||||
!*/
|
||||
|
||||
public:
|
||||
typedef T element_type;
|
||||
typedef deleter deleter_type;
|
||||
|
||||
explicit scoped_ptr (
|
||||
T* p = 0
|
||||
) : ptr(p) { }
|
||||
|
||||
~scoped_ptr()
|
||||
{
|
||||
if (ptr)
|
||||
{
|
||||
deleter del;
|
||||
del(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
void reset (
|
||||
T* p = 0
|
||||
)
|
||||
{
|
||||
if (ptr)
|
||||
{
|
||||
deleter del;
|
||||
del(ptr);
|
||||
}
|
||||
|
||||
ptr = p;
|
||||
}
|
||||
|
||||
T& operator*() const
|
||||
{
|
||||
DLIB_ASSERT(get() != 0,
|
||||
"\tscoped_ptr::operator*()"
|
||||
<< "\n\tget() can't be null if you are going to dereference it"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
T* operator->() const
|
||||
{
|
||||
DLIB_ASSERT(get() != 0,
|
||||
"\tscoped_ptr::operator*()"
|
||||
<< "\n\tget() can't be null"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
T* get() const
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return (ptr != 0);
|
||||
}
|
||||
|
||||
void swap(
|
||||
scoped_ptr& b
|
||||
)
|
||||
{
|
||||
std::swap(ptr,b.ptr);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
T* ptr;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename deleter
|
||||
>
|
||||
class scoped_ptr<T[],deleter> : noncopyable
|
||||
{
|
||||
/*!
|
||||
CONVENTION
|
||||
- get() == ptr
|
||||
!*/
|
||||
|
||||
public:
|
||||
typedef T element_type;
|
||||
|
||||
explicit scoped_ptr (
|
||||
T* p = 0
|
||||
) : ptr(p) { }
|
||||
|
||||
~scoped_ptr()
|
||||
{
|
||||
if (ptr)
|
||||
{
|
||||
deleter del;
|
||||
del(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
void reset (
|
||||
T* p = 0
|
||||
)
|
||||
{
|
||||
if (ptr)
|
||||
{
|
||||
deleter del;
|
||||
del(ptr);
|
||||
}
|
||||
ptr = p;
|
||||
}
|
||||
|
||||
T& operator[] (
|
||||
unsigned long idx
|
||||
) const
|
||||
{
|
||||
DLIB_ASSERT(get() != 0,
|
||||
"\tscoped_ptr::operator[]()"
|
||||
<< "\n\tget() can't be null if you are going to dereference it"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
return ptr[idx];
|
||||
}
|
||||
|
||||
T* get() const
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return (ptr != 0);
|
||||
}
|
||||
|
||||
void swap(
|
||||
scoped_ptr& b
|
||||
)
|
||||
{
|
||||
std::swap(ptr,b.ptr);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
T* ptr;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename deleter
|
||||
>
|
||||
void swap(
|
||||
scoped_ptr<T,deleter>& a,
|
||||
scoped_ptr<T,deleter>& b
|
||||
)
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_SCOPED_PTr_
|
||||
|
||||
|
||||
172
lib/3rdParty/dlib/include/dlib/smart_pointers/scoped_ptr_abstract.h
vendored
Normal file
172
lib/3rdParty/dlib/include/dlib/smart_pointers/scoped_ptr_abstract.h
vendored
Normal file
@@ -0,0 +1,172 @@
|
||||
// Copyright (C) 2007 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_SCOPED_PTr_ABSTRACT_
|
||||
#ifdef DLIB_SCOPED_PTr_ABSTRACT_
|
||||
|
||||
#include "../noncopyable.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <typename T>
|
||||
struct default_deleter
|
||||
{
|
||||
void operator() (
|
||||
T* item
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- if (T is an array type (e.g. int[])) then
|
||||
- performs "delete [] item;"
|
||||
- else
|
||||
- performs "delete item;"
|
||||
!*/
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename deleter = default_deleter<T>
|
||||
>
|
||||
class scoped_ptr : noncopyable
|
||||
{
|
||||
/*!
|
||||
REQUIREMENTS ON deleter
|
||||
Must be a function object that performs deallocation of a pointer
|
||||
of type T. For example, see the default_deleter type defined above.
|
||||
It must also not throw when constructed or when performing a delete.
|
||||
|
||||
INITIAL VALUE
|
||||
defined by constructor
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This is a smart pointer class inspired by the implementation of the scoped_ptr
|
||||
class found in the Boost C++ library. So this is a simple smart pointer
|
||||
class which guarantees that the pointer contained within it will always be
|
||||
deleted.
|
||||
|
||||
The class does not permit copying and so does not do any kind of
|
||||
reference counting. Thus it is very simply and quite fast.
|
||||
|
||||
Note that this class allows you to use pointers to arrays as well as
|
||||
pointers to single items. To let it know that it is supposed to point
|
||||
to an array you have to declare it using the bracket syntax. Consider
|
||||
the following examples:
|
||||
|
||||
// This is how you make a scoped pointer to a single thing
|
||||
scoped_ptr<int> single_item(new int);
|
||||
|
||||
// This is how you can use a scoped pointer to contain array pointers.
|
||||
// Note the use of []. This ensures that the proper version of delete
|
||||
// is called.
|
||||
scoped_ptr<int[]> array_of_ints(new int[50]);
|
||||
!*/
|
||||
|
||||
public:
|
||||
typedef T element_type;
|
||||
typedef deleter deleter_type;
|
||||
|
||||
explicit scoped_ptr (
|
||||
T* p = 0
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #get() == p
|
||||
!*/
|
||||
|
||||
~scoped_ptr(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- if (get() != 0) then
|
||||
- calls deleter()(get())
|
||||
(i.e. uses the deleter type to delete the pointer that is
|
||||
contained in this scoped pointer)
|
||||
!*/
|
||||
|
||||
void reset (
|
||||
T* p = 0
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- if (get() != 0) then
|
||||
- calls deleter()(get())
|
||||
(i.e. uses the deleter type to delete the pointer that is
|
||||
contained in this scoped pointer)
|
||||
- #get() == p
|
||||
(i.e. makes this object contain a pointer to p instead of whatever it
|
||||
used to contain)
|
||||
!*/
|
||||
|
||||
T& operator*(
|
||||
) const;
|
||||
/*!
|
||||
requires
|
||||
- get() != 0
|
||||
- T is NOT an array type (e.g. not int[])
|
||||
ensures
|
||||
- returns a reference to *get()
|
||||
!*/
|
||||
|
||||
T* operator->(
|
||||
) const;
|
||||
/*!
|
||||
requires
|
||||
- get() != 0
|
||||
- T is NOT an array type (e.g. not int[])
|
||||
ensures
|
||||
- returns the pointer contained in this object
|
||||
!*/
|
||||
|
||||
T& operator[](
|
||||
unsigned long idx
|
||||
) const;
|
||||
/*!
|
||||
requires
|
||||
- get() != 0
|
||||
- T is an array type (e.g. int[])
|
||||
ensures
|
||||
- returns get()[idx]
|
||||
!*/
|
||||
|
||||
T* get(
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns the pointer contained in this object
|
||||
!*/
|
||||
|
||||
operator bool(
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns get() != 0
|
||||
!*/
|
||||
|
||||
void swap(
|
||||
scoped_ptr& b
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- swaps *this and item
|
||||
!*/
|
||||
};
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void swap(
|
||||
scoped_ptr<T>& a,
|
||||
scoped_ptr<T>& b
|
||||
) { a.swap(b); }
|
||||
/*!
|
||||
provides a global swap function
|
||||
!*/
|
||||
}
|
||||
|
||||
#endif // DLIB_SCOPED_PTr_ABSTRACT_
|
||||
|
||||
|
||||
525
lib/3rdParty/dlib/include/dlib/smart_pointers/shared_ptr.h
vendored
Normal file
525
lib/3rdParty/dlib/include/dlib/smart_pointers/shared_ptr.h
vendored
Normal file
@@ -0,0 +1,525 @@
|
||||
// Copyright (C) 2007 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_SHARED_PTr_
|
||||
#define DLIB_SHARED_PTr_
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <typeinfo>
|
||||
#include <string> // for the exceptions
|
||||
#include "../algs.h"
|
||||
#include "shared_ptr_abstract.h"
|
||||
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class bad_weak_ptr: public std::exception {};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template<typename T> class weak_ptr;
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
struct shared_ptr_deleter
|
||||
{
|
||||
virtual void del(const void* p) = 0;
|
||||
virtual ~shared_ptr_deleter() {}
|
||||
|
||||
virtual void* get_deleter_void(const std::type_info& t) const = 0;
|
||||
/*!
|
||||
ensures
|
||||
- if (the deleter in this object has typeid() == t) then
|
||||
- returns a pointer to the deleter
|
||||
- else
|
||||
- return 0
|
||||
!*/
|
||||
};
|
||||
|
||||
struct shared_ptr_node;
|
||||
struct weak_ptr_node
|
||||
{
|
||||
weak_ptr_node (
|
||||
shared_ptr_node* sn
|
||||
) :
|
||||
ref_count(1),
|
||||
shared_node(sn)
|
||||
{
|
||||
DLIB_ASSERT(sn != 0,"");
|
||||
}
|
||||
|
||||
long ref_count;
|
||||
shared_ptr_node* shared_node;
|
||||
};
|
||||
|
||||
struct shared_ptr_node
|
||||
{
|
||||
shared_ptr_node(
|
||||
) :
|
||||
ref_count(1),
|
||||
del(0),
|
||||
weak_node(0)
|
||||
{}
|
||||
|
||||
long ref_count;
|
||||
shared_ptr_deleter* del;
|
||||
weak_ptr_node* weak_node;
|
||||
};
|
||||
|
||||
struct shared_ptr_static_cast {};
|
||||
struct shared_ptr_const_cast {};
|
||||
struct shared_ptr_dynamic_cast {};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template<typename T>
|
||||
class shared_ptr
|
||||
{
|
||||
/*!
|
||||
CONVENTION
|
||||
- get() == data
|
||||
- unique() == (shared_node != 0) && (shared_node->ref_count == 1)
|
||||
- if (shared_node != 0) then
|
||||
- use_count() == shared_node->ref_count
|
||||
- get() == a valid pointer
|
||||
- if (we are supposed to use the deleter) then
|
||||
- shared_node->del == the deleter to use
|
||||
- else
|
||||
- shared_node->del == 0
|
||||
- else
|
||||
- use_count() == 0
|
||||
- get() == 0
|
||||
|
||||
|
||||
- if (there are any weak_ptrs that reference this->data) then
|
||||
- shared_node->weak_node->ref_count == the number of referencing weak_ptrs
|
||||
- else
|
||||
- shared_node->weak_node == 0
|
||||
!*/
|
||||
|
||||
template <typename D>
|
||||
struct deleter_template : public shared_ptr_deleter
|
||||
{
|
||||
deleter_template(const D& d_) : d(d_) {}
|
||||
void del(const void* p) { d((T*)p); }
|
||||
D d;
|
||||
|
||||
void* get_deleter_void(const std::type_info& t) const
|
||||
{
|
||||
if (typeid(D) == t)
|
||||
return (void*)&d;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct default_deleter : public shared_ptr_deleter
|
||||
{
|
||||
void del(const void* p) { delete ((T*)p); }
|
||||
|
||||
void* get_deleter_void(const std::type_info&) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
|
||||
shared_ptr(
|
||||
) : data(0), shared_node(0) {}
|
||||
|
||||
template<typename Y>
|
||||
explicit shared_ptr(
|
||||
Y* p
|
||||
) : data(p)
|
||||
{
|
||||
DLIB_ASSERT(p != 0,
|
||||
"\tshared_ptr::shared_ptr(p)"
|
||||
<< "\n\tp can't be null"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
try
|
||||
{
|
||||
shared_node = new shared_ptr_node;
|
||||
shared_node->del = new default_deleter;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
delete p;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Y, typename D>
|
||||
shared_ptr(
|
||||
Y* p,
|
||||
const D& d
|
||||
) :
|
||||
data(p)
|
||||
{
|
||||
DLIB_ASSERT(p != 0,
|
||||
"\tshared_ptr::shared_ptr(p,d)"
|
||||
<< "\n\tp can't be null"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
try
|
||||
{
|
||||
shared_node = 0;
|
||||
shared_node = new shared_ptr_node;
|
||||
shared_node->del = new deleter_template<D>(d);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (shared_node) delete shared_node;
|
||||
d(p);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
~shared_ptr()
|
||||
{
|
||||
if ( shared_node != 0)
|
||||
{
|
||||
if (shared_node->ref_count == 1)
|
||||
{
|
||||
// delete the data in the appropriate way
|
||||
shared_node->del->del(data);
|
||||
delete shared_node->del;
|
||||
|
||||
// notify any weak_ptrs that the data has now expired
|
||||
if (shared_node->weak_node)
|
||||
shared_node->weak_node->shared_node = 0;
|
||||
|
||||
// finally delete the shared_node
|
||||
delete shared_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
shared_node->ref_count -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr(
|
||||
const shared_ptr& r
|
||||
)
|
||||
{
|
||||
data = r.data;
|
||||
shared_node = r.shared_node;
|
||||
if (shared_node)
|
||||
shared_node->ref_count += 1;
|
||||
}
|
||||
|
||||
template<typename Y>
|
||||
shared_ptr(
|
||||
const shared_ptr<Y>& r,
|
||||
const shared_ptr_static_cast&
|
||||
)
|
||||
{
|
||||
data = static_cast<T*>(r.data);
|
||||
if (data != 0)
|
||||
{
|
||||
shared_node = r.shared_node;
|
||||
shared_node->ref_count += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
shared_node = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Y>
|
||||
shared_ptr(
|
||||
const shared_ptr<Y>& r,
|
||||
const shared_ptr_const_cast&
|
||||
)
|
||||
{
|
||||
data = const_cast<T*>(r.data);
|
||||
if (data != 0)
|
||||
{
|
||||
shared_node = r.shared_node;
|
||||
shared_node->ref_count += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
shared_node = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Y>
|
||||
shared_ptr(
|
||||
const shared_ptr<Y>& r,
|
||||
const shared_ptr_dynamic_cast&
|
||||
)
|
||||
{
|
||||
data = dynamic_cast<T*>(r.data);
|
||||
if (data != 0)
|
||||
{
|
||||
shared_node = r.shared_node;
|
||||
shared_node->ref_count += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
shared_node = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Y>
|
||||
shared_ptr(
|
||||
const shared_ptr<Y>& r
|
||||
)
|
||||
{
|
||||
data = r.data;
|
||||
shared_node = r.shared_node;
|
||||
if (shared_node)
|
||||
shared_node->ref_count += 1;
|
||||
}
|
||||
|
||||
|
||||
template<typename Y>
|
||||
explicit shared_ptr(
|
||||
const weak_ptr<Y>& r
|
||||
)
|
||||
{
|
||||
if (r.expired())
|
||||
throw bad_weak_ptr();
|
||||
|
||||
data = r.data;
|
||||
shared_node = r.weak_node->shared_node;
|
||||
shared_node->ref_count += 1;
|
||||
}
|
||||
|
||||
template<typename Y>
|
||||
explicit shared_ptr(
|
||||
std::auto_ptr<Y>& r
|
||||
)
|
||||
{
|
||||
DLIB_ASSERT(r.get() != 0,
|
||||
"\tshared_ptr::shared_ptr(auto_ptr r)"
|
||||
<< "\n\tr.get() can't be null"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
shared_node = new shared_ptr_node;
|
||||
shared_node->del = new default_deleter;
|
||||
data = r.release();
|
||||
}
|
||||
|
||||
shared_ptr& operator= (
|
||||
const shared_ptr& r
|
||||
)
|
||||
{
|
||||
shared_ptr(r).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Y>
|
||||
shared_ptr& operator= (
|
||||
const shared_ptr<Y>& r
|
||||
)
|
||||
{
|
||||
shared_ptr(r).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Y>
|
||||
shared_ptr& operator= (
|
||||
std::auto_ptr<Y>& r
|
||||
)
|
||||
{
|
||||
DLIB_ASSERT(r.get() != 0,
|
||||
"\tshared_ptr::operator=(auto_ptr r)"
|
||||
<< "\n\tr.get() can't be null"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
reset();
|
||||
shared_node = new shared_ptr_node;
|
||||
shared_node->del = new default_deleter;
|
||||
data = r.release();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
shared_ptr().swap(*this);
|
||||
}
|
||||
|
||||
template<typename Y>
|
||||
void reset(Y* p)
|
||||
{
|
||||
DLIB_ASSERT(p != 0,
|
||||
"\tshared_ptr::reset(p)"
|
||||
<< "\n\tp can't be null"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
shared_ptr(p).swap(*this);
|
||||
}
|
||||
|
||||
template<typename Y, typename D>
|
||||
void reset(
|
||||
Y* p,
|
||||
const D& d
|
||||
)
|
||||
{
|
||||
DLIB_ASSERT(p != 0,
|
||||
"\tshared_ptr::reset(p,d)"
|
||||
<< "\n\tp can't be null"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
shared_ptr(p,d).swap(*this);
|
||||
}
|
||||
|
||||
T& operator*(
|
||||
) const
|
||||
{
|
||||
DLIB_ASSERT(get() != 0,
|
||||
"\tshared_ptr::operator*()"
|
||||
<< "\n\tget() can't be null if you are going to dereference it"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
return *data;
|
||||
}
|
||||
|
||||
T* operator->(
|
||||
) const
|
||||
{
|
||||
DLIB_ASSERT(get() != 0,
|
||||
"\tshared_ptr::operator->()"
|
||||
<< "\n\tget() can't be null"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
T* get() const { return data; }
|
||||
|
||||
bool unique() const
|
||||
{
|
||||
return use_count() == 1;
|
||||
}
|
||||
|
||||
long use_count() const
|
||||
{
|
||||
if (shared_node != 0)
|
||||
return shared_node->ref_count;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
operator bool(
|
||||
) const { return get() != 0; }
|
||||
|
||||
void swap(shared_ptr& b)
|
||||
{
|
||||
std::swap(data, b.data);
|
||||
std::swap(shared_node, b.shared_node);
|
||||
}
|
||||
|
||||
template <typename D>
|
||||
D* _get_deleter(
|
||||
) const
|
||||
{
|
||||
if (shared_node && shared_node->del)
|
||||
return static_cast<D*>(shared_node->del->get_deleter_void(typeid(D)));
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename Y>
|
||||
bool _private_less (
|
||||
const shared_ptr<Y>& rhs
|
||||
) const
|
||||
{
|
||||
return shared_node < rhs.shared_node;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template <typename Y> friend class shared_ptr;
|
||||
template <typename Y> friend class weak_ptr;
|
||||
|
||||
T* data;
|
||||
shared_ptr_node* shared_node;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template<typename T, typename U>
|
||||
bool operator== (
|
||||
const shared_ptr<T>& a,
|
||||
const shared_ptr<U>& b
|
||||
) { return a.get() == b.get(); }
|
||||
|
||||
template<typename T, typename U>
|
||||
bool operator!= (
|
||||
const shared_ptr<T>& a,
|
||||
const shared_ptr<U>& b
|
||||
) { return a.get() != b.get(); }
|
||||
|
||||
template<typename T, typename U>
|
||||
bool operator< (
|
||||
const shared_ptr<T>& a,
|
||||
const shared_ptr<U>& b
|
||||
)
|
||||
{
|
||||
return a._private_less(b);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void swap(
|
||||
shared_ptr<T>& a,
|
||||
shared_ptr<T>& b
|
||||
) { a.swap(b); }
|
||||
|
||||
template<typename T, typename U>
|
||||
shared_ptr<T> static_pointer_cast(
|
||||
const shared_ptr<U>& r
|
||||
)
|
||||
{
|
||||
return shared_ptr<T>(r, shared_ptr_static_cast());
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
shared_ptr<T> const_pointer_cast(
|
||||
shared_ptr<U> const & r
|
||||
)
|
||||
{
|
||||
return shared_ptr<T>(r, shared_ptr_const_cast());
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
shared_ptr<T> dynamic_pointer_cast(
|
||||
const shared_ptr<U>& r
|
||||
)
|
||||
{
|
||||
return shared_ptr<T>(r, shared_ptr_dynamic_cast());
|
||||
}
|
||||
|
||||
template<typename E, typename T, typename Y>
|
||||
std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p)
|
||||
{
|
||||
os << p.get();
|
||||
return os;
|
||||
}
|
||||
|
||||
template<typename D, typename T>
|
||||
D* get_deleter(const shared_ptr<T>& p)
|
||||
{
|
||||
return p.template _get_deleter<D>();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_SHARED_PTr_
|
||||
|
||||
406
lib/3rdParty/dlib/include/dlib/smart_pointers/shared_ptr_abstract.h
vendored
Normal file
406
lib/3rdParty/dlib/include/dlib/smart_pointers/shared_ptr_abstract.h
vendored
Normal file
@@ -0,0 +1,406 @@
|
||||
// Copyright (C) 2007 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_SHARED_PTr_ABSTRACT_
|
||||
#ifdef DLIB_SHARED_PTr_ABSTRACT_
|
||||
|
||||
#include "weak_ptr_abstract.h"
|
||||
#include <exception>
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class bad_weak_ptr: public std::exception {}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
class shared_ptr
|
||||
{
|
||||
/*!
|
||||
INITIAL VALUE
|
||||
defined by constructors
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object represents a reference counted smart pointer. Each shared_ptr
|
||||
contains a pointer to some object and when the last shared_ptr that points
|
||||
to the object is destructed or reset() then the object is guaranteed to be
|
||||
deleted.
|
||||
|
||||
This is an implementation of the std::tr1::shared_ptr template from the
|
||||
document ISO/IEC PDTR 19768, Proposed Draft Technical Report on C++
|
||||
Library Extensions. The only deviation from that document is that this
|
||||
shared_ptr is declared inside the dlib namespace rather than std::tr1.
|
||||
|
||||
THREAD SAFETY
|
||||
This object is not thread safe. Especially so since it is
|
||||
reference counted. So you should take care to not have two shared_ptr
|
||||
objects in different threads that point to the same object.
|
||||
|
||||
If you want a thread safe version of this object you should use the
|
||||
dlib::shared_ptr_thread_safe object instead.
|
||||
!*/
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
|
||||
shared_ptr(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #get() == 0
|
||||
- #use_count() == 0
|
||||
!*/
|
||||
|
||||
template<typename Y>
|
||||
explicit shared_ptr(
|
||||
Y* p
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- p is convertible to a T* type pointer
|
||||
- p can be deleted by calling "delete p;" and doing so will not throw exceptions
|
||||
- p != 0
|
||||
ensures
|
||||
- #get() == p
|
||||
- #use_count() == 1
|
||||
- #*this object owns the pointer p
|
||||
throws
|
||||
- std::bad_alloc
|
||||
if this exception is thrown then "delete p;" is called
|
||||
!*/
|
||||
|
||||
template<typename Y, typename D>
|
||||
shared_ptr(
|
||||
Y* p,
|
||||
const D& d
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- p is convertible to a T* type pointer
|
||||
- D is copy constructable (and the copy constructor of D doesn't throw)
|
||||
- p can be deleted by calling "d(p);" and doing so will not throw exceptions
|
||||
- p != 0
|
||||
ensures
|
||||
- #get() == p
|
||||
- #use_count() == 1
|
||||
- #*this object owns the pointer p
|
||||
throws
|
||||
- std::bad_alloc
|
||||
if this exception is thrown then "d(p);" is called
|
||||
!*/
|
||||
|
||||
shared_ptr(
|
||||
const shared_ptr& r
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #get() == #r.get()
|
||||
- #use_count() == #r.use_count()
|
||||
- If r is empty, constructs an empty shared_ptr object; otherwise, constructs
|
||||
a shared_ptr object that shares ownership with r.
|
||||
!*/
|
||||
|
||||
template<typename Y>
|
||||
shared_ptr(
|
||||
const shared_ptr<Y>& r
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- Y* is convertible to T*
|
||||
ensures
|
||||
- #get() == #r.get()
|
||||
- #use_count() == #r.use_count()
|
||||
- If r is empty, constructs an empty shared_ptr object; otherwise, constructs
|
||||
a shared_ptr object that shares ownership with r.
|
||||
!*/
|
||||
|
||||
template<typename Y>
|
||||
explicit shared_ptr(
|
||||
const weak_ptr<Y>& r
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- Y* is convertible to T*
|
||||
ensures
|
||||
- #get() == #r.get()
|
||||
- #use_count() == #r.use_count()
|
||||
- If r is empty, constructs an empty shared_ptr object; otherwise, constructs
|
||||
a shared_ptr object that shares ownership with r.
|
||||
throws
|
||||
- bad_weak_ptr
|
||||
this exception is thrown if r.expired() == true
|
||||
!*/
|
||||
|
||||
template<typename Y>
|
||||
explicit shared_ptr(
|
||||
std::auto_ptr<Y>& r
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- p.get() != 0
|
||||
- p.release() is convertible to a T* type pointer
|
||||
- p.release() can be deleted by calling "delete p.release();" and doing so will not throw exceptions
|
||||
ensures
|
||||
- #get() == p.release()
|
||||
- #use_count() == 1
|
||||
- #r.get() == 0
|
||||
- #*this object owns the pointer p.release()
|
||||
throws
|
||||
- std::bad_alloc
|
||||
!*/
|
||||
|
||||
~shared_ptr(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- if (use_count() > 1)
|
||||
- this object destroys itself but otherwise has no effect (i.e.
|
||||
the pointer get() is still valid and shared between the remaining
|
||||
shared_ptr objects)
|
||||
- else if (use_count() == 1)
|
||||
- deletes the pointer get() by calling delete (or using the deleter passed
|
||||
to the constructor if one was passed in)
|
||||
- else
|
||||
- in this case get() == 0 so there is nothing to do so nothing occurs
|
||||
!*/
|
||||
|
||||
shared_ptr& operator= (
|
||||
const shared_ptr& r
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- equivalent to shared_ptr(r).swap(*this).
|
||||
- returns #*this
|
||||
!*/
|
||||
|
||||
template<typename Y>
|
||||
shared_ptr& operator= (
|
||||
const shared_ptr<Y>& r
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- Y* is convertible to T*
|
||||
ensures
|
||||
- equivalent to shared_ptr(r).swap(*this).
|
||||
- returns #*this
|
||||
!*/
|
||||
|
||||
template<typename Y>
|
||||
shared_ptr& operator= (
|
||||
std::auto_ptr<Y>& r
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- p.get() != 0
|
||||
- p.release() is convertible to a T* type pointer
|
||||
- p.release() can be deleted by calling "delete p.release();" and doing so will not throw exceptions
|
||||
ensures
|
||||
- equivalent to shared_ptr(r).swap(*this).
|
||||
- returns #*this
|
||||
!*/
|
||||
|
||||
void reset(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- equivalent to shared_ptr().swap(*this)
|
||||
!*/
|
||||
|
||||
template<typename Y>
|
||||
void reset(
|
||||
Y* p
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- p is convertible to a T* type pointer
|
||||
- p can be deleted by calling "delete p;" and doing so will not throw exceptions
|
||||
- p != 0
|
||||
ensures
|
||||
- equivalent to shared_ptr(p).swap(*this)
|
||||
!*/
|
||||
|
||||
template<typename Y, typename D>
|
||||
void reset(
|
||||
Y* p,
|
||||
const D& d
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- p is convertible to a T* type pointer
|
||||
- D is copy constructable (and the copy constructor of D doesn't throw)
|
||||
- p can be deleted by calling "d(p);" and doing so will not throw exceptions
|
||||
- p != 0
|
||||
ensures
|
||||
- equivalent to shared_ptr(p,d).swap(*this)
|
||||
!*/
|
||||
|
||||
T* get(
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns the stored pointer
|
||||
!*/
|
||||
|
||||
T& operator*(
|
||||
) const;
|
||||
/*!
|
||||
requires
|
||||
- get() != 0
|
||||
ensures
|
||||
- returns a reference to *get()
|
||||
!*/
|
||||
|
||||
T* operator->(
|
||||
) const;
|
||||
/*!
|
||||
requires
|
||||
- get() != 0
|
||||
ensures
|
||||
- returns get()
|
||||
!*/
|
||||
|
||||
bool unique(
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns (use_count() == 1)
|
||||
!*/
|
||||
|
||||
long use_count(
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- The number of shared_ptr objects, *this included, that share ownership with *this, or 0 when *this
|
||||
is empty.
|
||||
!*/
|
||||
|
||||
operator bool(
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns (get() != 0)
|
||||
!*/
|
||||
|
||||
void swap(
|
||||
shared_ptr& b
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- swaps *this and item
|
||||
!*/
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template<typename T, typename U>
|
||||
bool operator== (
|
||||
const shared_ptr<T>& a,
|
||||
const shared_ptr<U>& b
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- returns a.get() == b.get()
|
||||
!*/
|
||||
|
||||
template<typename T, typename U>
|
||||
bool operator!= (
|
||||
const shared_ptr<T>& a,
|
||||
const shared_ptr<U>& b
|
||||
) { return a.get() != b.get(); }
|
||||
/*!
|
||||
ensures
|
||||
- returns a.get() != b.get()
|
||||
!*/
|
||||
|
||||
template<typename T, typename U>
|
||||
bool operator< (
|
||||
const shared_ptr<T>& a,
|
||||
const shared_ptr<U>& b
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- Defines an operator< on shared_ptr types appropriate for use in the associative
|
||||
containers.
|
||||
!*/
|
||||
|
||||
template<typename T>
|
||||
void swap(
|
||||
shared_ptr<T>& a,
|
||||
shared_ptr<T>& b
|
||||
) { a.swap(b); }
|
||||
/*!
|
||||
provides a global swap function
|
||||
!*/
|
||||
|
||||
template<typename T, typename U>
|
||||
shared_ptr<T> static_pointer_cast(
|
||||
const shared_ptr<U>& r
|
||||
);
|
||||
/*!
|
||||
- if (r.get() == 0) then
|
||||
- returns shared_ptr<T>()
|
||||
- else
|
||||
- returns a shared_ptr<T> object that stores static_cast<T*>(r.get()) and shares
|
||||
ownership with r.
|
||||
!*/
|
||||
|
||||
template<typename T, typename U>
|
||||
shared_ptr<T> const_pointer_cast(
|
||||
const shared_ptr<U>& r
|
||||
);
|
||||
/*!
|
||||
- if (r.get() == 0) then
|
||||
- returns shared_ptr<T>()
|
||||
- else
|
||||
- returns a shared_ptr<T> object that stores const_cast<T*>(r.get()) and shares
|
||||
ownership with r.
|
||||
!*/
|
||||
|
||||
template<typename T, typename U>
|
||||
shared_ptr<T> dynamic_pointer_cast(
|
||||
const shared_ptr<U>& r
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- if (dynamic_cast<T*>(r.get()) returns a nonzero value) then
|
||||
- returns a shared_ptr<T> object that stores a copy of
|
||||
dynamic_cast<T*>(r.get()) and shares ownership with r
|
||||
- else
|
||||
- returns an empty shared_ptr<T> object.
|
||||
!*/
|
||||
|
||||
template<typename E, typename T, typename Y>
|
||||
std::basic_ostream<E, T> & operator<< (
|
||||
std::basic_ostream<E, T> & os,
|
||||
const shared_ptr<Y>& p
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- performs os << p.get()
|
||||
- returns os
|
||||
!*/
|
||||
|
||||
template<typename D, typename T>
|
||||
D* get_deleter(
|
||||
const shared_ptr<T>& p
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- if (*this owns a deleter d of type cv-unqualified D) then
|
||||
- returns &d
|
||||
- else
|
||||
- returns 0
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_SHARED_PTr_ABSTRACT_
|
||||
|
||||
497
lib/3rdParty/dlib/include/dlib/smart_pointers/shared_ptr_thread_safe.h
vendored
Normal file
497
lib/3rdParty/dlib/include/dlib/smart_pointers/shared_ptr_thread_safe.h
vendored
Normal file
@@ -0,0 +1,497 @@
|
||||
// Copyright (C) 2007 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_SHARED_THREAD_SAFE_PTr_
|
||||
#define DLIB_SHARED_THREAD_SAFE_PTr_
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <typeinfo>
|
||||
#include <string> // for the exceptions
|
||||
#include "../algs.h"
|
||||
#include "shared_ptr_thread_safe_abstract.h"
|
||||
#include "../threads/threads_kernel.h"
|
||||
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
struct shared_ptr_thread_safe_deleter
|
||||
{
|
||||
virtual void del(const void* p) = 0;
|
||||
virtual ~shared_ptr_thread_safe_deleter() {}
|
||||
|
||||
virtual void* get_deleter_void(const std::type_info& t) const = 0;
|
||||
/*!
|
||||
ensures
|
||||
- if (the deleter in this object has typeid() == t) then
|
||||
- returns a pointer to the deleter
|
||||
- else
|
||||
- return 0
|
||||
!*/
|
||||
};
|
||||
|
||||
struct shared_ptr_thread_safe_node
|
||||
{
|
||||
shared_ptr_thread_safe_node(
|
||||
) :
|
||||
ref_count(1),
|
||||
del(0)
|
||||
{}
|
||||
|
||||
dlib::mutex m;
|
||||
long ref_count;
|
||||
shared_ptr_thread_safe_deleter* del;
|
||||
};
|
||||
|
||||
struct shared_ptr_ts_static_cast {};
|
||||
struct shared_ptr_ts_const_cast {};
|
||||
struct shared_ptr_ts_dynamic_cast {};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template<typename T>
|
||||
class shared_ptr_thread_safe
|
||||
{
|
||||
/*!
|
||||
CONVENTION
|
||||
- get() == data
|
||||
- unique() == (shared_node != 0) && (shared_node->ref_count == 1)
|
||||
- if (shared_node != 0) then
|
||||
- use_count() == shared_node->ref_count
|
||||
- get() == a valid pointer
|
||||
- if (we are supposed to use the deleter) then
|
||||
- shared_node->del == the deleter to use
|
||||
- else
|
||||
- shared_node->del == 0
|
||||
- else
|
||||
- use_count() == 0
|
||||
- get() == 0
|
||||
|
||||
!*/
|
||||
|
||||
template <typename D>
|
||||
struct deleter_template : public shared_ptr_thread_safe_deleter
|
||||
{
|
||||
deleter_template(const D& d_) : d(d_) {}
|
||||
void del(const void* p) { d((T*)p); }
|
||||
D d;
|
||||
|
||||
void* get_deleter_void(const std::type_info& t) const
|
||||
{
|
||||
if (typeid(D) == t)
|
||||
return (void*)&d;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
|
||||
shared_ptr_thread_safe(
|
||||
) : data(0), shared_node(0) {}
|
||||
|
||||
template<typename Y>
|
||||
explicit shared_ptr_thread_safe(
|
||||
Y* p
|
||||
) : data(p)
|
||||
{
|
||||
DLIB_ASSERT(p != 0,
|
||||
"\tshared_ptr::shared_ptr_thread_safe(p)"
|
||||
<< "\n\tp can't be null"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
try
|
||||
{
|
||||
shared_node = new shared_ptr_thread_safe_node;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
delete p;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Y, typename D>
|
||||
shared_ptr_thread_safe(
|
||||
Y* p,
|
||||
const D& d
|
||||
) :
|
||||
data(p)
|
||||
{
|
||||
DLIB_ASSERT(p != 0,
|
||||
"\tshared_ptr::shared_ptr_thread_safe(p,d)"
|
||||
<< "\n\tp can't be null"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
try
|
||||
{
|
||||
shared_node = 0;
|
||||
shared_node = new shared_ptr_thread_safe_node;
|
||||
shared_node->del = new deleter_template<D>(d);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (shared_node) delete shared_node;
|
||||
d(p);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
~shared_ptr_thread_safe()
|
||||
{
|
||||
if ( shared_node != 0)
|
||||
{
|
||||
shared_node->m.lock();
|
||||
if (shared_node->ref_count == 1)
|
||||
{
|
||||
// delete the data in the appropriate way
|
||||
if (shared_node->del)
|
||||
{
|
||||
shared_node->del->del(data);
|
||||
|
||||
shared_node->m.unlock();
|
||||
delete shared_node->del;
|
||||
}
|
||||
else
|
||||
{
|
||||
shared_node->m.unlock();
|
||||
delete data;
|
||||
}
|
||||
|
||||
// finally delete the shared_node
|
||||
delete shared_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
shared_node->ref_count -= 1;
|
||||
shared_node->m.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr_thread_safe(
|
||||
const shared_ptr_thread_safe& r
|
||||
)
|
||||
{
|
||||
data = r.data;
|
||||
shared_node = r.shared_node;
|
||||
if (shared_node)
|
||||
{
|
||||
auto_mutex M(shared_node->m);
|
||||
shared_node->ref_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Y>
|
||||
shared_ptr_thread_safe(
|
||||
const shared_ptr_thread_safe<Y>& r,
|
||||
const shared_ptr_ts_static_cast&
|
||||
)
|
||||
{
|
||||
data = static_cast<T*>(r.data);
|
||||
if (data != 0)
|
||||
{
|
||||
shared_node = r.shared_node;
|
||||
auto_mutex M(shared_node->m);
|
||||
shared_node->ref_count += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
shared_node = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Y>
|
||||
shared_ptr_thread_safe(
|
||||
const shared_ptr_thread_safe<Y>& r,
|
||||
const shared_ptr_ts_const_cast&
|
||||
)
|
||||
{
|
||||
data = const_cast<T*>(r.data);
|
||||
if (data != 0)
|
||||
{
|
||||
shared_node = r.shared_node;
|
||||
auto_mutex M(shared_node->m);
|
||||
shared_node->ref_count += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
shared_node = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Y>
|
||||
shared_ptr_thread_safe(
|
||||
const shared_ptr_thread_safe<Y>& r,
|
||||
const shared_ptr_ts_dynamic_cast&
|
||||
)
|
||||
{
|
||||
data = dynamic_cast<T*>(r.data);
|
||||
if (data != 0)
|
||||
{
|
||||
shared_node = r.shared_node;
|
||||
auto_mutex M(shared_node->m);
|
||||
shared_node->ref_count += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
shared_node = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Y>
|
||||
shared_ptr_thread_safe(
|
||||
const shared_ptr_thread_safe<Y>& r
|
||||
)
|
||||
{
|
||||
data = r.data;
|
||||
shared_node = r.shared_node;
|
||||
if (shared_node)
|
||||
{
|
||||
auto_mutex M(shared_node->m);
|
||||
shared_node->ref_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename Y>
|
||||
explicit shared_ptr_thread_safe(
|
||||
std::auto_ptr<Y>& r
|
||||
)
|
||||
{
|
||||
DLIB_ASSERT(r.get() != 0,
|
||||
"\tshared_ptr::shared_ptr_thread_safe(auto_ptr r)"
|
||||
<< "\n\tr.get() can't be null"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
shared_node = new shared_ptr_thread_safe_node;
|
||||
data = r.release();
|
||||
}
|
||||
|
||||
shared_ptr_thread_safe& operator= (
|
||||
const shared_ptr_thread_safe& r
|
||||
)
|
||||
{
|
||||
shared_ptr_thread_safe(r).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Y>
|
||||
shared_ptr_thread_safe& operator= (
|
||||
const shared_ptr_thread_safe<Y>& r
|
||||
)
|
||||
{
|
||||
shared_ptr_thread_safe(r).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Y>
|
||||
shared_ptr_thread_safe& operator= (
|
||||
std::auto_ptr<Y>& r
|
||||
)
|
||||
{
|
||||
DLIB_ASSERT(r.get() != 0,
|
||||
"\tshared_ptr::operator=(auto_ptr r)"
|
||||
<< "\n\tr.get() can't be null"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
reset();
|
||||
shared_node = new shared_ptr_thread_safe_node;
|
||||
data = r.release();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
shared_ptr_thread_safe().swap(*this);
|
||||
}
|
||||
|
||||
template<typename Y>
|
||||
void reset(Y* p)
|
||||
{
|
||||
DLIB_ASSERT(p != 0,
|
||||
"\tshared_ptr::reset(p)"
|
||||
<< "\n\tp can't be null"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
shared_ptr_thread_safe(p).swap(*this);
|
||||
}
|
||||
|
||||
template<typename Y, typename D>
|
||||
void reset(
|
||||
Y* p,
|
||||
const D& d
|
||||
)
|
||||
{
|
||||
DLIB_ASSERT(p != 0,
|
||||
"\tshared_ptr::reset(p,d)"
|
||||
<< "\n\tp can't be null"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
shared_ptr_thread_safe(p,d).swap(*this);
|
||||
}
|
||||
|
||||
T& operator*(
|
||||
) const
|
||||
{
|
||||
DLIB_ASSERT(get() != 0,
|
||||
"\tshared_ptr::operator*()"
|
||||
<< "\n\tget() can't be null if you are going to dereference it"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
return *data;
|
||||
}
|
||||
|
||||
T* operator->(
|
||||
) const
|
||||
{
|
||||
DLIB_ASSERT(get() != 0,
|
||||
"\tshared_ptr::operator->()"
|
||||
<< "\n\tget() can't be null"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
T* get() const { return data; }
|
||||
|
||||
bool unique() const
|
||||
{
|
||||
return use_count() == 1;
|
||||
}
|
||||
|
||||
long use_count() const
|
||||
{
|
||||
if (shared_node != 0)
|
||||
{
|
||||
auto_mutex M(shared_node->m);
|
||||
return shared_node->ref_count;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
operator bool(
|
||||
) const { return get() != 0; }
|
||||
|
||||
void swap(shared_ptr_thread_safe& b)
|
||||
{
|
||||
std::swap(data, b.data);
|
||||
std::swap(shared_node, b.shared_node);
|
||||
}
|
||||
|
||||
template <typename D>
|
||||
D* _get_deleter(
|
||||
) const
|
||||
{
|
||||
if (shared_node)
|
||||
{
|
||||
auto_mutex M(shared_node->m);
|
||||
if (shared_node->del)
|
||||
return static_cast<D*>(shared_node->del->get_deleter_void(typeid(D)));
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Y>
|
||||
bool _private_less (
|
||||
const shared_ptr_thread_safe<Y>& rhs
|
||||
) const
|
||||
{
|
||||
return shared_node < rhs.shared_node;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template <typename Y> friend class shared_ptr_thread_safe;
|
||||
|
||||
T* data;
|
||||
shared_ptr_thread_safe_node* shared_node;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template<typename T, typename U>
|
||||
bool operator== (
|
||||
const shared_ptr_thread_safe<T>& a,
|
||||
const shared_ptr_thread_safe<U>& b
|
||||
) { return a.get() == b.get(); }
|
||||
|
||||
template<typename T, typename U>
|
||||
bool operator!= (
|
||||
const shared_ptr_thread_safe<T>& a,
|
||||
const shared_ptr_thread_safe<U>& b
|
||||
) { return a.get() != b.get(); }
|
||||
|
||||
template<typename T, typename U>
|
||||
bool operator< (
|
||||
const shared_ptr_thread_safe<T>& a,
|
||||
const shared_ptr_thread_safe<U>& b
|
||||
)
|
||||
{
|
||||
return a._private_less(b);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void swap(
|
||||
shared_ptr_thread_safe<T>& a,
|
||||
shared_ptr_thread_safe<T>& b
|
||||
) { a.swap(b); }
|
||||
|
||||
template<typename T, typename U>
|
||||
shared_ptr_thread_safe<T> static_pointer_cast(
|
||||
const shared_ptr_thread_safe<U>& r
|
||||
)
|
||||
{
|
||||
return shared_ptr_thread_safe<T>(r, shared_ptr_ts_static_cast());
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
shared_ptr_thread_safe<T> const_pointer_cast(
|
||||
shared_ptr_thread_safe<U> const & r
|
||||
)
|
||||
{
|
||||
return shared_ptr_thread_safe<T>(r, shared_ptr_ts_const_cast());
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
shared_ptr_thread_safe<T> dynamic_pointer_cast(
|
||||
const shared_ptr_thread_safe<U>& r
|
||||
)
|
||||
{
|
||||
return shared_ptr_thread_safe<T>(r, shared_ptr_ts_dynamic_cast());
|
||||
}
|
||||
|
||||
template<typename E, typename T, typename Y>
|
||||
std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr_thread_safe<Y> const & p)
|
||||
{
|
||||
os << p.get();
|
||||
return os;
|
||||
}
|
||||
|
||||
template<typename D, typename T>
|
||||
D* get_deleter(const shared_ptr_thread_safe<T>& p)
|
||||
{
|
||||
return p.template _get_deleter<D>();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_SHARED_THREAD_SAFE_PTr_
|
||||
|
||||
384
lib/3rdParty/dlib/include/dlib/smart_pointers/shared_ptr_thread_safe_abstract.h
vendored
Normal file
384
lib/3rdParty/dlib/include/dlib/smart_pointers/shared_ptr_thread_safe_abstract.h
vendored
Normal file
@@ -0,0 +1,384 @@
|
||||
// Copyright (C) 2007 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_SHARED_PTr_THREAD_SAFE_ABSTRACT_
|
||||
#ifdef DLIB_SHARED_PTr_THREAD_SAFE_ABSTRACT_
|
||||
|
||||
#include <exception>
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
class shared_ptr_thread_safe
|
||||
{
|
||||
/*!
|
||||
INITIAL VALUE
|
||||
defined by constructors
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object represents a reference counted smart pointer. Each shared_ptr_thread_safe
|
||||
contains a pointer to some object and when the last shared_ptr_thread_safe that points
|
||||
to the object is destructed or reset() then the object is guaranteed to be
|
||||
deleted.
|
||||
|
||||
This is an implementation of the std::tr1::shared_ptr template from the
|
||||
document ISO/IEC PDTR 19768, Proposed Draft Technical Report on C++
|
||||
Library Extensions. The only deviation from that document is that this
|
||||
shared_ptr_thread_safe is declared inside the dlib namespace rather than std::tr1,
|
||||
this one is explicitly thread safe, and there isn't a corresponding weak_ptr.
|
||||
|
||||
THREAD SAFETY
|
||||
This is a version of the shared_ptr object that can be used to share pointers
|
||||
across more than one thread. Note however, that individual instances of this object
|
||||
must still have access to them serialized by a mutex lock if they are to be modified
|
||||
by more than one thread. But if you have two different shared_ptr_thread_safe objects
|
||||
that both point to the same thing from different threads then you are safe.
|
||||
!*/
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
|
||||
shared_ptr_thread_safe(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #get() == 0
|
||||
- #use_count() == 0
|
||||
!*/
|
||||
|
||||
template<typename Y>
|
||||
explicit shared_ptr_thread_safe(
|
||||
Y* p
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- p is convertible to a T* type pointer
|
||||
- p can be deleted by calling "delete p;" and doing so will not throw exceptions
|
||||
- p != 0
|
||||
ensures
|
||||
- #get() == p
|
||||
- #use_count() == 1
|
||||
- #*this object owns the pointer p
|
||||
throws
|
||||
- std::bad_alloc
|
||||
if this exception is thrown then "delete p;" is called
|
||||
!*/
|
||||
|
||||
template<typename Y, typename D>
|
||||
shared_ptr_thread_safe(
|
||||
Y* p,
|
||||
const D& d
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- p is convertible to a T* type pointer
|
||||
- D is copy constructable (and the copy constructor of D doesn't throw)
|
||||
- p can be deleted by calling "d(p);" and doing so will not throw exceptions
|
||||
- p != 0
|
||||
ensures
|
||||
- #get() == p
|
||||
- #use_count() == 1
|
||||
- #*this object owns the pointer p
|
||||
throws
|
||||
- std::bad_alloc
|
||||
if this exception is thrown then "d(p);" is called
|
||||
!*/
|
||||
|
||||
shared_ptr_thread_safe(
|
||||
const shared_ptr_thread_safe& r
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #get() == #r.get()
|
||||
- #use_count() == #r.use_count()
|
||||
- If r is empty, constructs an empty shared_ptr_thread_safe object; otherwise, constructs
|
||||
a shared_ptr_thread_safe object that shares ownership with r.
|
||||
!*/
|
||||
|
||||
template<typename Y>
|
||||
shared_ptr_thread_safe(
|
||||
const shared_ptr_thread_safe<Y>& r
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- Y* is convertible to T*
|
||||
ensures
|
||||
- #get() == #r.get()
|
||||
- #use_count() == #r.use_count()
|
||||
- If r is empty, constructs an empty shared_ptr_thread_safe object; otherwise, constructs
|
||||
a shared_ptr_thread_safe object that shares ownership with r.
|
||||
!*/
|
||||
|
||||
template<typename Y>
|
||||
explicit shared_ptr_thread_safe(
|
||||
std::auto_ptr<Y>& r
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- p.get() != 0
|
||||
- p.release() is convertible to a T* type pointer
|
||||
- p.release() can be deleted by calling "delete p.release();" and doing so will not throw exceptions
|
||||
ensures
|
||||
- #get() == p.release()
|
||||
- #use_count() == 1
|
||||
- #r.get() == 0
|
||||
- #*this object owns the pointer p.release()
|
||||
throws
|
||||
- std::bad_alloc
|
||||
!*/
|
||||
|
||||
~shared_ptr_thread_safe(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- if (use_count() > 1)
|
||||
- this object destroys itself but otherwise has no effect (i.e.
|
||||
the pointer get() is still valid and shared between the remaining
|
||||
shared_ptr_thread_safe objects)
|
||||
- else if (use_count() == 1)
|
||||
- deletes the pointer get() by calling delete (or using the deleter passed
|
||||
to the constructor if one was passed in)
|
||||
- else
|
||||
- in this case get() == 0 so there is nothing to do so nothing occurs
|
||||
!*/
|
||||
|
||||
shared_ptr_thread_safe& operator= (
|
||||
const shared_ptr_thread_safe& r
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- equivalent to shared_ptr_thread_safe(r).swap(*this).
|
||||
- returns #*this
|
||||
!*/
|
||||
|
||||
template<typename Y>
|
||||
shared_ptr_thread_safe& operator= (
|
||||
const shared_ptr_thread_safe<Y>& r
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- Y* is convertible to T*
|
||||
ensures
|
||||
- equivalent to shared_ptr_thread_safe(r).swap(*this).
|
||||
- returns #*this
|
||||
!*/
|
||||
|
||||
template<typename Y>
|
||||
shared_ptr_thread_safe& operator= (
|
||||
std::auto_ptr<Y>& r
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- p.get() != 0
|
||||
- p.release() is convertible to a T* type pointer
|
||||
- p.release() can be deleted by calling "delete p.release();" and doing so will not throw exceptions
|
||||
ensures
|
||||
- equivalent to shared_ptr_thread_safe(r).swap(*this).
|
||||
- returns #*this
|
||||
!*/
|
||||
|
||||
void reset(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- equivalent to shared_ptr_thread_safe().swap(*this)
|
||||
!*/
|
||||
|
||||
template<typename Y>
|
||||
void reset(
|
||||
Y* p
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- p is convertible to a T* type pointer
|
||||
- p can be deleted by calling "delete p;" and doing so will not throw exceptions
|
||||
- p != 0
|
||||
ensures
|
||||
- equivalent to shared_ptr_thread_safe(p).swap(*this)
|
||||
!*/
|
||||
|
||||
template<typename Y, typename D>
|
||||
void reset(
|
||||
Y* p,
|
||||
const D& d
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- p is convertible to a T* type pointer
|
||||
- D is copy constructable (and the copy constructor of D doesn't throw)
|
||||
- p can be deleted by calling "d(p);" and doing so will not throw exceptions
|
||||
- p != 0
|
||||
ensures
|
||||
- equivalent to shared_ptr_thread_safe(p,d).swap(*this)
|
||||
!*/
|
||||
|
||||
T* get(
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns the stored pointer
|
||||
!*/
|
||||
|
||||
T& operator*(
|
||||
) const;
|
||||
/*!
|
||||
requires
|
||||
- get() != 0
|
||||
ensures
|
||||
- returns a reference to *get()
|
||||
!*/
|
||||
|
||||
T* operator->(
|
||||
) const;
|
||||
/*!
|
||||
requires
|
||||
- get() != 0
|
||||
ensures
|
||||
- returns get()
|
||||
!*/
|
||||
|
||||
bool unique(
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns (use_count() == 1)
|
||||
!*/
|
||||
|
||||
long use_count(
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- The number of shared_ptr_thread_safe objects, *this included, that share ownership with *this, or 0 when *this
|
||||
is empty.
|
||||
!*/
|
||||
|
||||
operator bool(
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns (get() != 0)
|
||||
!*/
|
||||
|
||||
void swap(
|
||||
shared_ptr_thread_safe& b
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- swaps *this and item
|
||||
!*/
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template<typename T, typename U>
|
||||
bool operator== (
|
||||
const shared_ptr_thread_safe<T>& a,
|
||||
const shared_ptr_thread_safe<U>& b
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- returns a.get() == b.get()
|
||||
!*/
|
||||
|
||||
template<typename T, typename U>
|
||||
bool operator!= (
|
||||
const shared_ptr_thread_safe<T>& a,
|
||||
const shared_ptr_thread_safe<U>& b
|
||||
) { return a.get() != b.get(); }
|
||||
/*!
|
||||
ensures
|
||||
- returns a.get() != b.get()
|
||||
!*/
|
||||
|
||||
template<typename T, typename U>
|
||||
bool operator< (
|
||||
const shared_ptr_thread_safe<T>& a,
|
||||
const shared_ptr_thread_safe<U>& b
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- Defines an operator< on shared_ptr_thread_safe types appropriate for use in the associative
|
||||
containers.
|
||||
!*/
|
||||
|
||||
template<typename T>
|
||||
void swap(
|
||||
shared_ptr_thread_safe<T>& a,
|
||||
shared_ptr_thread_safe<T>& b
|
||||
) { a.swap(b); }
|
||||
/*!
|
||||
provides a global swap function
|
||||
!*/
|
||||
|
||||
template<typename T, typename U>
|
||||
shared_ptr_thread_safe<T> static_pointer_cast(
|
||||
const shared_ptr_thread_safe<U>& r
|
||||
);
|
||||
/*!
|
||||
- if (r.get() == 0) then
|
||||
- returns shared_ptr_thread_safe<T>()
|
||||
- else
|
||||
- returns a shared_ptr_thread_safe<T> object that stores static_cast<T*>(r.get()) and shares
|
||||
ownership with r.
|
||||
!*/
|
||||
|
||||
template<typename T, typename U>
|
||||
shared_ptr_thread_safe<T> const_pointer_cast(
|
||||
const shared_ptr_thread_safe<U>& r
|
||||
);
|
||||
/*!
|
||||
- if (r.get() == 0) then
|
||||
- returns shared_ptr_thread_safe<T>()
|
||||
- else
|
||||
- returns a shared_ptr_thread_safe<T> object that stores const_cast<T*>(r.get()) and shares
|
||||
ownership with r.
|
||||
!*/
|
||||
|
||||
template<typename T, typename U>
|
||||
shared_ptr_thread_safe<T> dynamic_pointer_cast(
|
||||
const shared_ptr_thread_safe<U>& r
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- if (dynamic_cast<T*>(r.get()) returns a nonzero value) then
|
||||
- returns a shared_ptr_thread_safe<T> object that stores a copy of
|
||||
dynamic_cast<T*>(r.get()) and shares ownership with r
|
||||
- else
|
||||
- returns an empty shared_ptr_thread_safe<T> object.
|
||||
!*/
|
||||
|
||||
template<typename E, typename T, typename Y>
|
||||
std::basic_ostream<E, T> & operator<< (
|
||||
std::basic_ostream<E, T> & os,
|
||||
const shared_ptr_thread_safe<Y>& p
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- performs os << p.get()
|
||||
- returns os
|
||||
!*/
|
||||
|
||||
template<typename D, typename T>
|
||||
D* get_deleter(
|
||||
const shared_ptr_thread_safe<T>& p
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- if (*this owns a deleter d of type cv-unqualified D) then
|
||||
- returns &d
|
||||
- else
|
||||
- returns 0
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_SHARED_PTr_THREAD_SAFE_ABSTRACT_
|
||||
|
||||
225
lib/3rdParty/dlib/include/dlib/smart_pointers/weak_ptr.h
vendored
Normal file
225
lib/3rdParty/dlib/include/dlib/smart_pointers/weak_ptr.h
vendored
Normal file
@@ -0,0 +1,225 @@
|
||||
// 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_
|
||||
|
||||
|
||||
193
lib/3rdParty/dlib/include/dlib/smart_pointers/weak_ptr_abstract.h
vendored
Normal file
193
lib/3rdParty/dlib/include/dlib/smart_pointers/weak_ptr_abstract.h
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
// Copyright (C) 2007 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_WEAK_PTr_ABSTRACT_
|
||||
#ifdef DLIB_WEAK_PTr_ABSTRACT_
|
||||
|
||||
#include "shared_ptr_abstract.h"
|
||||
|
||||
namespace dlib {
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
class weak_ptr
|
||||
{
|
||||
|
||||
/*!
|
||||
INITIAL VALUE
|
||||
defined by constructor
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
The weak_ptr class template stores a weak reference to an object that is
|
||||
already managed by a shared_ptr. To access the object, a weak_ptr can
|
||||
be converted to a shared_ptr using the member function lock().
|
||||
|
||||
This is an implementation of the std::tr1::weak_ptr template from the
|
||||
document ISO/IEC PDTR 19768, Proposed Draft Technical Report on C++
|
||||
Library Extensions. The only deviation from that document is that this
|
||||
shared_ptr is declared inside the dlib namespace rather than std::tr1.
|
||||
!*/
|
||||
|
||||
public:
|
||||
typedef T element_type;
|
||||
|
||||
weak_ptr(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #use_count() == 0
|
||||
- creates an empty weak_ptr
|
||||
!*/
|
||||
|
||||
template<typename Y>
|
||||
weak_ptr(
|
||||
const shared_ptr<Y>& r
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- Y* must be convertible to T*
|
||||
ensures
|
||||
- if (r is empty) then
|
||||
- constructs an empty weak_ptr object
|
||||
- else
|
||||
- constructs a weak_ptr object that shares ownership with r and
|
||||
stores a copy of the pointer stored in r.
|
||||
- #use_count() == #r.use_count()
|
||||
!*/
|
||||
|
||||
weak_ptr(
|
||||
const weak_ptr& r
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- if (r is empty) then
|
||||
- constructs an empty weak_ptr object
|
||||
- else
|
||||
- constructs a weak_ptr object that shares ownership with r and
|
||||
stores a copy of the pointer stored in r.
|
||||
- #use_count() == #r.use_count()
|
||||
!*/
|
||||
|
||||
template<typename Y>
|
||||
weak_ptr(
|
||||
const weak_ptr<Y>& r
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- Y* must be convertible to T*
|
||||
ensures
|
||||
- if (r is empty) then
|
||||
- constructs an empty weak_ptr object
|
||||
- else
|
||||
- constructs a weak_ptr object that shares ownership with r and
|
||||
stores a copy of the pointer stored in r.
|
||||
- #use_count() == #r.use_count()
|
||||
!*/
|
||||
|
||||
~weak_ptr(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- destroys this weak_ptr object but has no effect on the object its
|
||||
stored pointer points to.
|
||||
!*/
|
||||
|
||||
weak_ptr& operator= (
|
||||
const weak_ptr& r
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- equivalent to weak_ptr(r).swap(*this)
|
||||
!*/
|
||||
|
||||
template<typename Y>
|
||||
weak_ptr& operator= (
|
||||
const weak_ptr<Y>& r
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- Y* must be convertible to T*
|
||||
ensures
|
||||
- equivalent to weak_ptr(r).swap(*this)
|
||||
!*/
|
||||
|
||||
template<typename Y>
|
||||
weak_ptr& operator=(
|
||||
const shared_ptr<Y>& r
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- Y* must be convertible to T*
|
||||
ensures
|
||||
- equivalent to weak_ptr(r).swap(*this)
|
||||
!*/
|
||||
|
||||
long use_count(
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- if (*this is empty) then
|
||||
- returns 0
|
||||
- else
|
||||
- returns the number of shared_ptr instances that share ownership
|
||||
with *this
|
||||
!*/
|
||||
|
||||
bool expired(
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns (use_count() == 0)
|
||||
!*/
|
||||
|
||||
shared_ptr<T> lock(
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- if (expired()) then
|
||||
- returns shared_ptr<T>()
|
||||
- else
|
||||
- returns shared_ptr<T>(*this)
|
||||
!*/
|
||||
|
||||
void reset(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- equivalent to weak_ptr().swap(*this)
|
||||
!*/
|
||||
|
||||
void swap(
|
||||
weak_ptr<T>& b
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- swaps *this and item
|
||||
!*/
|
||||
|
||||
};
|
||||
|
||||
template<typename T, typename U>
|
||||
bool operator< (
|
||||
const weak_ptr<T>& a,
|
||||
const weak_ptr<U>& b
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- Defines an operator< on shared_ptr types appropriate for use in the associative
|
||||
containers.
|
||||
!*/
|
||||
|
||||
template<typename T>
|
||||
void swap(
|
||||
weak_ptr<T>& a,
|
||||
weak_ptr<T> & b
|
||||
) { a.swap(b); }
|
||||
/*!
|
||||
provides a global swap function
|
||||
!*/
|
||||
}
|
||||
|
||||
#endif // DLIB_WEAK_PTr_ABSTRACT_
|
||||
|
||||
|
||||
Reference in New Issue
Block a user