Skip to content

Instantly share code, notes, and snippets.

@alno
Created July 23, 2009 06:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alno/152492 to your computer and use it in GitHub Desktop.
Save alno/152492 to your computer and use it in GitHub Desktop.
Test properties in C++
#include <iostream>
/**
* Класс, предоставляющий общие сервисы для свойств, а также используемый для хранения в классе позиции свойств.
*/
template <
typename PropertyOwner // Класс владельца
>
class properties {
public:
static PropertyOwner * owner( void * property ) { // Получить указатель на владельца по указателю на свойство
int aai = (int)&(((PropertyOwner*)0)->__properties);
return (PropertyOwner *)((char*)property - aai);
}
};
/**
* Шаблон класса свойства
*/
template <
typename PropertyOwner, // Класс владельца
typename PropertyType, // Тип свойства
PropertyType (PropertyOwner::*getter)(), // Геттер
void (PropertyOwner::*setter)(PropertyType) > // Сеттер
class property {
public:
/**
* Чтение свойства - вызов геттера
*/
operator PropertyType() {
return (properties<PropertyOwner>::owner( this )->*getter)();
}
/**
* Запись в свойство - вызов сеттера
*/
void operator = ( const PropertyType & value ) {
(properties<PropertyOwner>::owner( this )->*setter)( value );
}
};
// Макросы для удобного определения свойств /////////
/**
* Начать объявления свойств в классе cls
*/
#define properties_start(cls) union { properties<cls> __properties;
/**
* Закончить объявление свойств в классе cls
*/
#define properties_end() };
/**
* Объявить свойство в классе cls типа type c геттером getter и сеттером setter
*/
#define property(cls,type,getter,setter) property<cls,type,&cls::getter,&cls::setter>
/*
* Ввод и вывод для свойств
*/
template <
typename PropertyOwner,
typename PropertyType,
PropertyType (PropertyOwner::*getter)(),
void (PropertyOwner::*setter)(PropertyType) >
std::ostream & operator << ( std::ostream & os, property<PropertyOwner,PropertyType,getter,setter> prop ) {
return os << (PropertyType)prop;
}
template <
typename PropertyOwner,
typename PropertyType,
PropertyType (PropertyOwner::*getter)(),
void (PropertyOwner::*setter)(PropertyType) >
std::istream & operator >> ( std::istream & is, property<PropertyOwner,PropertyType,getter,setter> prop ) {
PropertyType value;
is >> value;
prop = value;
return is;
}
class CClass {
private:
int a_value;
/**
* Геттер
*/
int getA() {
return a_value;
}
/**
* Сеттер
*/
void setA( int a ) {
a_value = a;
}
public:
properties_start( CClass ); // Начало свойств
property( CClass, int, getA, setA ) a; // Свойство
properties_end(); // Конец свойств
};
int main( int argc, char ** argv ) {
CClass c;
c.a = 145;
std::cout << "Class size:" << sizeof( CClass ) << std::endl;
std::cout << c.a << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment