/
AnySharedPointer.h
117 lines (94 loc) · 3.64 KB
/
AnySharedPointer.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
114
115
116
117
// Copyright (C) 2012-2014 Leap Motion, Inc. All rights reserved.
#pragma once
#include "SharedPointerSlot.h"
struct AnySharedPointer {
public:
AnySharedPointer(void);
AnySharedPointer(AnySharedPointer&& rhs);
explicit AnySharedPointer(const AnySharedPointer& rhs);
template<class T>
explicit AnySharedPointer(const std::shared_ptr<T>& rhs) {
// Delegate the remainder to the assign operation:
new (m_space) SharedPointerSlotT<T>(rhs);
}
~AnySharedPointer(void);
protected:
unsigned char m_space[sizeof(SharedPointerSlot)];
public:
// Convenience method to cast the space to a slot
SharedPointerSlot* slot(void) { return (SharedPointerSlot*) m_space; }
const SharedPointerSlot* slot(void) const { return (const SharedPointerSlot*) m_space; }
explicit operator bool(void) const { return slot()->operator bool(); }
SharedPointerSlot& operator*(void) { return *slot(); }
const SharedPointerSlot& operator*(void) const { return *slot(); }
SharedPointerSlot* operator->(void) { return slot(); }
const SharedPointerSlot* operator->(void) const { return slot(); }
template<class T>
SharedPointerSlotT<T>& as(void) const { return (SharedPointerSlotT<T>&)*slot(); }
bool operator==(const AnySharedPointer& rhs) const {
return *slot() == *rhs.slot();
}
template<class T>
bool operator==(const std::shared_ptr<T>& rhs) const {
return *slot() == rhs;
}
/// <summary>
/// Default for std library sorting of unique elements
/// </summary>
bool operator<(const AnySharedPointer& rhs) const { return *slot() < *rhs.slot();}
/// <summary>
/// Default for std library sorting of repeatable elements
/// </summary>
bool operator<=(const AnySharedPointer& rhs) const { return *slot() <= *rhs.slot();}
bool operator>(const AnySharedPointer& rhs) const { return *slot() > *rhs.slot();}
bool operator>=(const AnySharedPointer& rhs) const { return *slot() >= *rhs.slot();}
/// <summary>
/// Copy assignment operator
/// </summary>
/// <remarks>
/// Consumer beware: This is a transformative assignment. The true polymorphic
/// type will be carried from the right-hand side into this element, which is a
/// different behavior from how things are normally done during assignment. Other
/// than that, however, the behavior is very similar to boost::any's assignment
/// implementation.
/// </remarks>
SharedPointerSlot& operator=(const AnySharedPointer& rhs) {
return **this = *rhs;
}
/// <summary>
/// Convenience overload for slot assignment
/// </summary>
SharedPointerSlot& operator=(const SharedPointerSlot& rhs) {
return *slot() = rhs;
}
/// <summary>
/// Convenience overload for shared pointer assignment
/// </summary>
template<class T>
void operator=(const std::shared_ptr<T>& rhs) {
**this = rhs;
}
};
/// <summary>
/// Convenience implementation of AnySharedPointer which is initially of type T
/// </summary>
template<class T>
class AnySharedPointerT:
public AnySharedPointer
{
public:
AnySharedPointerT(void) {
new (m_space) SharedPointerSlotT<T>();
}
// Convenience method to cast the space to a slot, but with the expected type
SharedPointerSlotT<T>* slot(void) { return (SharedPointerSlotT<T>*) m_space; }
const SharedPointerSlotT<T>* slot(void) const { return (const SharedPointerSlotT<T>*) m_space; }
T& operator*(void) { return *slot()->get(); }
const T& operator*(void) const { return **slot(); }
T* operator->(void) { return slot()->get().get(); }
const T* operator->(void) const { return slot()->get().get(); }
};
template<class T>
inline bool operator==(const std::shared_ptr<T>& lhs, const AnySharedPointer& rhs) {
return rhs == lhs;
}