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
|
#ifndef PROPERTY_H
#define PROPERTY_H
#include <iostream>
template<class Context, class T> struct Property_index;
template<class Context, class T>
class property {
Context* view; // an Item needs to access values in its context
T (Context::*Getter)();
void (Context::*Setter)(T);
protected:
T get() const { return (Getter) ? (view->*Getter)() : 0; }
void set(T val) { if (Setter) (view->*Setter)(val); }
public:
property(Context* v,
T (Context::*G)() = &Context::get,
void (Context::*S)(T) = &Context::set)
:view(v), Getter(G), Setter(S) { }
operator T() const { return get(); }
property& operator=(T val) { set(val); return *this; }
property& operator+=(T val) { set(get() + val); return *this; }
property& operator=(const property &other) { set(T(other)); return *this; }
// specialized operations:
T operator->() { return get(); }
// string specific
property<Property_index<Context,T>,char> operator[](int i);
int size() { return (view->*Getter)().size(); }
};
template<class Context, class T>
struct Property_index { // inefficient
property<Context,T>* p;
int i;
Property_index(property<Context,T>* pp, int ii) : p(pp), i(ii) { }
char get() const { return p->get()[i]; }
void set(char ch) { T v = p->get(); v[i] = ch; p->set(v); }
};
template<class Context, class T>
property<Property_index<Context,T>,char> property<Context,T>::operator[](int i)
{
return property<Property_index<Context,T>,char>(new Property_index<Context,T>(this,i));
// leaks
}
template<class Context, class T>
inline ostream& operator<<(ostream& s, property<Context,T> p)
{
s << T(p);
}
template<class Context, class T>
inline istream& operator>>(istream& s, property<Context,T>& p)
{
T t;
s >> t;
p = t;
}
/* examples
property<TTreeView,TTreeNodes*> Items;
Items(this, &get, &set);
*/
#endif
|