-
-
Notifications
You must be signed in to change notification settings - Fork 1k
/
some.h
113 lines (103 loc) · 2.43 KB
/
some.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#ifndef __SG_SOME_H__
#define __SG_SOME_H__
#include <shogun/lib/config.h>
#ifdef HAVE_CXX11
#include <memory>
#include <shogun/base/SGObject.h>
namespace shogun
{
/** @class Shogun synonym for the std::shared_ptr. Employs
* exactly the same strategy for reference counting
* as std::shared_ptr: any operation involving copying increases
* the count and once deleted this wrapper decreases the counter.
*
* Note: Due to SG_REF/SG_UNREF used in Shogun now, it also imitates
* Shogun references so that shared_ptr counter should always
* be equal to the Shogun's object reference count. This will stay
* until SG_REF/SG_UNREF are gone.
*
*/
template <typename T>
class Some : protected std::shared_ptr<T>
{
public:
Some() = delete;
Some(const std::shared_ptr<T>& shared);
Some(const Some<T>& other);
Some(Some<T>&& other);
Some& operator=(const Some<T>& other);
Some& operator=(T* other);
~Some();
/** Casts the underlying object back to raw pointer
*
* @return raw pointer (with SG_REF)
*/
operator T*();
/** Call member function or access member of T
*
* @return raw pointer (without SG_REF)
*/
T* operator->();
private:
using std::shared_ptr<T>::get;
using std::shared_ptr<T>::reset;
};
template <typename T>
Some<T>::Some(const std::shared_ptr<T>& shared)
: std::shared_ptr<T>(shared)
{
}
template <typename T>
Some<T>::Some(const Some<T>& other)
: std::shared_ptr<T>(other)
{
}
template <typename T>
Some<T>::Some(Some<T>&& other)
: std::shared_ptr<T>(other)
{
}
template <typename T>
Some<T>::~Some()
{
}
template <typename T>
Some<T>& Some<T>::operator=(T* other)
{
this->reset(other);
SG_REF(this->get());
return *this;
}
template <typename T>
Some<T>::operator T*()
{
T* ptr = this->get();
SG_REF(ptr);
return ptr;
}
template <typename T>
T* Some<T>::operator->()
{
T* ptr = this->get();
return ptr;
}
/** Creates an instance of any class
* that is wrapped with a shared pointer like
* structure @ref Some
*
* @param args arguments to construct instance of T with (T should
* have compatible constructor)
*
* @return a shared pointer that holds created instance of @ref T
*
*/
template <typename T, class... Args>
Some<T> some(Args&&... args)
{
T* ptr = new T(args...);
SG_REF(ptr);
return std::shared_ptr<T>(ptr, [](T* p) { SG_UNREF(p); });
}
};
#endif /* HAVE_CXX11 */
#endif /* __SG_SOME_H__ */