Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/nall/property.hpp
2 views
1
#ifndef NALL_PROPERTY_HPP
2
#define NALL_PROPERTY_HPP
3
4
//nall::property implements ownership semantics into container classes
5
//example: property<owner>::readonly<type> implies that only owner has full
6
//access to type; and all other code has readonly access.
7
//
8
//this code relies on extended friend semantics from C++0x to work, as it
9
//declares a friend class via a template paramter. it also exploits a bug in
10
//G++ 4.x to work even in C++98 mode.
11
//
12
//if compiling elsewhere, simply remove the friend class and private semantics
13
14
//property can be used either of two ways:
15
//struct foo {
16
// property<foo>::readonly<bool> x;
17
// property<foo>::readwrite<int> y;
18
//};
19
//-or-
20
//struct foo : property<foo> {
21
// readonly<bool> x;
22
// readwrite<int> y;
23
//};
24
25
//return types are const T& (byref) instead of T (byval) to avoid major speed
26
//penalties for objects with expensive copy constructors
27
28
//operator-> provides access to underlying object type:
29
//readonly<Object> foo;
30
//foo->bar();
31
//... will call Object::bar();
32
33
//operator='s reference is constant so as to avoid leaking a reference handle
34
//that could bypass access restrictions
35
36
//both constant and non-constant operators are provided, though it may be
37
//necessary to cast first, for instance:
38
//struct foo : property<foo> { readonly<int> bar; } object;
39
//int main() { int value = const_cast<const foo&>(object); }
40
41
//writeonly is useful for objects that have non-const reads, but const writes.
42
//however, to avoid leaking handles, the interface is very restricted. the only
43
//way to write is via operator=, which requires conversion via eg copy
44
//constructor. example:
45
//struct foo {
46
// foo(bool value) { ... }
47
//};
48
//writeonly<foo> bar;
49
//bar = true;
50
51
#ifdef _MSC_VER
52
#define DUMB(X)
53
#else
54
#define DUMB(X) X
55
#endif
56
57
namespace nall {
58
template<typename C> struct property {
59
template<typename T> struct traits { typedef T type; };
60
61
template<typename T> struct readonly {
62
const T* operator->() const { return &value; }
63
const T& operator()() const { return value; }
64
operator const T&() const { return value; }
65
DUMB(private:)
66
T* operator->() { return &value; }
67
operator T&() { return value; }
68
const T& operator=(const T& value_) { return value = value_; }
69
T value;
70
DUMB(friend class traits<C>::type);
71
};
72
73
template<typename T> struct writeonly {
74
void operator=(const T& value_) { value = value_; }
75
DUMB(private:)
76
const T* operator->() const { return &value; }
77
const T& operator()() const { return value; }
78
operator const T&() const { return value; }
79
T* operator->() { return &value; }
80
operator T&() { return value; }
81
T value;
82
DUMB(friend class traits<C>::type);
83
};
84
85
template<typename T> struct readwrite {
86
const T* operator->() const { return &value; }
87
const T& operator()() const { return value; }
88
operator const T&() const { return value; }
89
T* operator->() { return &value; }
90
operator T&() { return value; }
91
const T& operator=(const T& value_) { return value = value_; }
92
T value;
93
};
94
};
95
}
96
97
#endif
98
99