#ifndef NALL_PROPERTY_HPP1#define NALL_PROPERTY_HPP23//nall::property implements ownership semantics into container classes4//example: property<owner>::readonly<type> implies that only owner has full5//access to type; and all other code has readonly access.6//7//this code relies on extended friend semantics from C++0x to work, as it8//declares a friend class via a template paramter. it also exploits a bug in9//G++ 4.x to work even in C++98 mode.10//11//if compiling elsewhere, simply remove the friend class and private semantics1213//property can be used either of two ways:14//struct foo {15// property<foo>::readonly<bool> x;16// property<foo>::readwrite<int> y;17//};18//-or-19//struct foo : property<foo> {20// readonly<bool> x;21// readwrite<int> y;22//};2324//return types are const T& (byref) instead of T (byval) to avoid major speed25//penalties for objects with expensive copy constructors2627//operator-> provides access to underlying object type:28//readonly<Object> foo;29//foo->bar();30//... will call Object::bar();3132//operator='s reference is constant so as to avoid leaking a reference handle33//that could bypass access restrictions3435//both constant and non-constant operators are provided, though it may be36//necessary to cast first, for instance:37//struct foo : property<foo> { readonly<int> bar; } object;38//int main() { int value = const_cast<const foo&>(object); }3940//writeonly is useful for objects that have non-const reads, but const writes.41//however, to avoid leaking handles, the interface is very restricted. the only42//way to write is via operator=, which requires conversion via eg copy43//constructor. example:44//struct foo {45// foo(bool value) { ... }46//};47//writeonly<foo> bar;48//bar = true;4950#ifdef _MSC_VER51#define DUMB(X)52#else53#define DUMB(X) X54#endif5556namespace nall {57template<typename C> struct property {58template<typename T> struct traits { typedef T type; };5960template<typename T> struct readonly {61const T* operator->() const { return &value; }62const T& operator()() const { return value; }63operator const T&() const { return value; }64DUMB(private:)65T* operator->() { return &value; }66operator T&() { return value; }67const T& operator=(const T& value_) { return value = value_; }68T value;69DUMB(friend class traits<C>::type);70};7172template<typename T> struct writeonly {73void operator=(const T& value_) { value = value_; }74DUMB(private:)75const T* operator->() const { return &value; }76const T& operator()() const { return value; }77operator const T&() const { return value; }78T* operator->() { return &value; }79operator T&() { return value; }80T value;81DUMB(friend class traits<C>::type);82};8384template<typename T> struct readwrite {85const T* operator->() const { return &value; }86const T& operator()() const { return value; }87operator const T&() const { return value; }88T* operator->() { return &value; }89operator T&() { return value; }90const T& operator=(const T& value_) { return value = value_; }91T value;92};93};94}9596#endif979899