1 |
|
|
/** |
2 |
|
|
* This file is part of the CernVM File System. |
3 |
|
|
*/ |
4 |
|
|
|
5 |
|
|
#ifndef CVMFS_UTIL_POINTER_H_ |
6 |
|
|
#define CVMFS_UTIL_POINTER_H_ |
7 |
|
|
|
8 |
|
|
#include <cstdlib> |
9 |
|
|
|
10 |
|
|
#include "util/single_copy.h" |
11 |
|
|
|
12 |
|
|
#ifdef CVMFS_NAMESPACE_GUARD |
13 |
|
|
namespace CVMFS_NAMESPACE_GUARD { |
14 |
|
|
#endif |
15 |
|
|
|
16 |
|
|
/** |
17 |
|
|
* Type Trait: |
18 |
|
|
* "Static" assertion that a template parameter is a pointer |
19 |
|
|
*/ |
20 |
|
|
template<typename T> |
21 |
|
|
struct IsPointer { static const bool value = false; }; |
22 |
|
|
template<typename T> |
23 |
|
|
struct IsPointer<T*> { static const bool value = true; }; |
24 |
|
|
|
25 |
|
|
|
26 |
|
|
template <class T, class DerivedT> |
27 |
|
|
class UniquePtrBase : SingleCopy { |
28 |
|
|
public: |
29 |
|
|
inline UniquePtrBase() : ref_(NULL) {} |
30 |
|
56 |
inline explicit UniquePtrBase(T *ref) : ref_(ref) { } |
31 |
|
56 |
inline ~UniquePtrBase() { Free(); } |
32 |
|
|
|
33 |
|
|
inline operator bool() const { return IsValid(); } |
34 |
|
364 |
inline T* operator->() const { return ref_; } |
35 |
|
28 |
inline operator T*() { return ref_; } |
36 |
|
|
inline DerivedT& operator=(T *ref) { |
37 |
|
|
if (ref_ != ref) { |
38 |
|
|
Free(); |
39 |
|
|
ref_ = ref; |
40 |
|
|
} |
41 |
|
|
return *(static_cast<DerivedT*>(this)); |
42 |
|
|
} |
43 |
|
|
inline T* weak_ref() const { return ref_; } |
44 |
|
28 |
inline bool IsValid() const { return (ref_ != NULL); } |
45 |
|
|
inline T* Release() { T* r = ref_; ref_ = NULL; return r; } |
46 |
|
|
inline void Destroy() { Free(); ref_ = NULL; } |
47 |
|
|
|
48 |
|
|
protected: |
49 |
|
56 |
void Free() { |
50 |
|
56 |
static_cast<DerivedT*>(this)->Free(); |
51 |
|
56 |
} |
52 |
|
|
T *ref_; |
53 |
|
|
}; |
54 |
|
|
|
55 |
|
|
|
56 |
|
|
template <class T> |
57 |
|
56 |
class UniquePtr : public UniquePtrBase<T, UniquePtr<T> > { |
58 |
|
|
friend class UniquePtrBase<T, UniquePtr<T> >; |
59 |
|
|
|
60 |
|
|
private: |
61 |
|
|
typedef UniquePtrBase<T, UniquePtr<T> > BaseT; |
62 |
|
|
public: |
63 |
|
|
using BaseT::operator=; |
64 |
|
|
inline UniquePtr() : BaseT(NULL) { } |
65 |
|
56 |
inline explicit UniquePtr(T *ref) : BaseT(ref) { } |
66 |
|
|
inline T& operator*() const { return *BaseT::ref_; } |
67 |
|
|
protected: |
68 |
✓✓✗✗
|
56 |
void Free() { delete BaseT::ref_; } |
69 |
|
|
}; |
70 |
|
|
|
71 |
|
|
|
72 |
|
|
template <> |
73 |
|
|
class UniquePtr<void> : public UniquePtrBase<void, UniquePtr<void> > { |
74 |
|
|
private: |
75 |
|
|
typedef UniquePtrBase<void, UniquePtr<void> > BaseT; |
76 |
|
|
public: |
77 |
|
|
friend class UniquePtrBase<void, UniquePtr<void> >; |
78 |
|
|
using BaseT::operator=; |
79 |
|
|
inline UniquePtr() : BaseT(NULL) { } |
80 |
|
|
inline explicit UniquePtr(void *ref) : BaseT(ref) { } |
81 |
|
|
protected: |
82 |
|
|
void Free() { |
83 |
|
|
if (IsValid()) { |
84 |
|
|
free(BaseT::ref_); |
85 |
|
|
} |
86 |
|
|
} |
87 |
|
|
}; |
88 |
|
|
|
89 |
|
|
template <> |
90 |
|
|
class UniquePtr<unsigned char> |
91 |
|
|
: public UniquePtrBase<unsigned char, UniquePtr<unsigned char> > { |
92 |
|
|
private: |
93 |
|
|
typedef UniquePtrBase<unsigned char, UniquePtr<unsigned char> > BaseT; |
94 |
|
|
public: |
95 |
|
|
friend class UniquePtrBase<unsigned char, UniquePtr<unsigned char> >; |
96 |
|
|
using BaseT::operator=; |
97 |
|
|
inline UniquePtr() : BaseT(NULL) { } |
98 |
|
|
inline explicit UniquePtr(unsigned char *ref) : BaseT(ref) { } |
99 |
|
|
protected: |
100 |
|
|
void Free() { |
101 |
|
|
if (IsValid()) { |
102 |
|
|
free(BaseT::ref_); |
103 |
|
|
} |
104 |
|
|
} |
105 |
|
|
}; |
106 |
|
|
|
107 |
|
|
|
108 |
|
|
#ifdef CVMFS_NAMESPACE_GUARD |
109 |
|
|
} // namespace CVMFS_NAMESPACE_GUARD |
110 |
|
|
#endif |
111 |
|
|
|
112 |
|
|
#endif // CVMFS_UTIL_POINTER_H_ |