aboutsummaryrefslogtreecommitdiffstats
path: root/apps/X11/VCL/property
blob: aee9edaa9adcd3c6a0025499aa697c396a8ac047 (plain) (blame)
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