Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> правильная реализация reflection+introspection, в С/С++ путем написания плагина для GCC. 
:(
    Опции темы
boostcoder
Дата 23.7.2011, 20:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



начитавшись манов по разработке расширений для GCC решил: хватит с меня макросов и кодогенерации осложненной нехваткой возможностей препроцессора и информации о типах доступной на стадии препроцессирования!!! smile буду писать плагин.

интересует мнение форумчан:
какой вы видите reflection и introspection в С/С++? и чего вам от них надо?

спасибо.


Это сообщение отредактировал(а) boostcoder - 24.7.2011, 16:32
PM WWW   Вверх
xvr
Дата 24.7.2011, 11:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(boostcoder @  23.7.2011,  20:57 Найти цитируемый пост)
буду писать плагин.

Может взять готовый? GCC-XML

PM MAIL   Вверх
boostcoder
Дата 24.7.2011, 14:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(xvr @  24.7.2011,  11:32 Найти цитируемый пост)
Может взять готовый? GCC-XML

я как-то пытался понять что это и с чем его едят, и ничего понял smile

Добавлено через 26 секунд
попытаюсь снова..
PM WWW   Вверх
boostcoder
Дата 24.7.2011, 15:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



что-то ответов маловато.. наверное всех уже достали мои темы связанные с кодогенерацией smile 

что мне видится необходимым:
1. генерация сериализаторов/десериализаторов. думаю использовать для этого прагмы.
Код

// полная сериализация/десериализация.
#pragma serialize full
struct type {
   int x;
   int y;
};

// частичная сериализация/десериализация.
#pragma serialize partial x
struct type {
   int x;
   int y;
};

// раздельная сериализация/десериализация.
#pragma serialize in(x), out(x, y)
struct type {
   int x;
   int y;
};




в процессе написания...
PM WWW   Вверх
volatile
Дата 24.7.2011, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



 smile 

boostcoder, плагины это конечно хорошо, но вы ведь навсегда свой проект привязываете к конеретной среде разработки.
Хорошо если вам никогда не придется переписывать это на другую IDE...
Но кто даст гарантию, что это вдруг когда-нибудь не понадобится?
PM MAIL   Вверх
boostcoder
Дата 24.7.2011, 15:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(volatile @  24.7.2011,  15:44 Найти цитируемый пост)
к конеретной среде разработки

Цитата(volatile @  24.7.2011,  15:44 Найти цитируемый пост)
переписывать это на другую IDE

эм... плагин для GCC.

Цитата(volatile @  24.7.2011,  15:44 Найти цитируемый пост)
Но кто даст гарантию, что это вдруг когда-нибудь не понадобится?

так а проблема в чем? я и сам могу gcc и mingw`ы собирать. или я вас не понял?
PM WWW   Вверх
volatile
Дата 24.7.2011, 16:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



я имел ввиду если нужен будет не gcc.

PM MAIL   Вверх
boostcoder
Дата 24.7.2011, 16:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(volatile @  24.7.2011,  16:09 Найти цитируемый пост)
нужен будет не gcc

разве такое возможно? зачем? почему?
PM WWW   Вверх
xvr
Дата 24.7.2011, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(boostcoder @  24.7.2011,  14:21 Найти цитируемый пост)
я как-то пытался понять что это и с чем его едят, и ничего понял

Это backend для gcc. Вместо генерации кода выводит внутреннее представление в виде XML. Правда выводится далеко не все внутреннее представление, а только декларации (вроде). Для introspection/reflection должно хватить

Есть еще один путь - парсить отладочную информацию (DWARF2 например)


PM MAIL   Вверх
boostcoder
Дата 24.7.2011, 16:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(xvr @  24.7.2011,  16:11 Найти цитируемый пост)
Это backend для gcc. Вместо генерации кода выводит внутреннее представление в виде XML.

да. уже проверил.

Цитата(xvr @  24.7.2011,  16:11 Найти цитируемый пост)
 только декларации (вроде)

да. тоже проверил.
и да, должно хватить.

из этого:
Код


struct type1 {
};

struct type2 {
   int x;
};

struct type3: type2 {
   int y;
};



получаем это:
Код

  <Function id="_60" name="__builtin_isgreaterequal" returns="_144" context="_1" location="f0:138" file="f0" line="138" extern="1" attributes="nothrow const">
    <Ellipsis/>
  </Function>
  <Struct id="_61" name="type1" context="_1" mangled="5type1" demangled="type1" location="f1:2" file="f1" line="2" artificial="1" size="8" align="8" members="_155 _156 _157 _158 " bases=""/>
  <Struct id="_62" name="type2" context="_1" mangled="5type2" demangled="type2" location="f1:5" file="f1" line="5" artificial="1" size="32" align="32" members="_159 _160 _161 _162 _163 " bases=""/>
  <Struct id="_63" name="type3" context="_1" mangled="5type3" demangled="type3" location="f1:9" file="f1" line="9" artificial="1" size="64" align="32" members="_164 _165 _166 _167 _168 " bases="_62 ">
    <Base type="_62" access="public" virtual="0" offset="0"/>
  </Struct>
  <Function id="_64" name="__builtin_log10f" returns="_142" context="_1" mangled="log10f" location="f0:64" file="f0" line="64" extern="1" attributes="nothrow">
    <Argument type="_142" location="f0:64" file="f0" line="64"/>
  </Function>
  <Function id="_65" name="__builtin_log10l" returns="_143" context="_1" mangled="log10l" location="f0:65" file="f0" line="65" extern="1" attributes="nothrow">
    <Argument type="_143" location="f0:65" file="f0" line="65"/>
  </Function>
  <Function id="_66" name="__builtin_ctzl" returns="_145" context="_1" location="f0:97" file="f0" line="97" extern="1" attributes="nothrow const">
    <Argument type="_169" location="f0:97" file="f0" line="97"/>
  </Function>
  <Function id="_67" name="__builtin_powif" returns="_142" context="_1" location="f0:73" file="f0" line="73" extern="1" attributes="nothrow pure no vops">
    <Argument type="_142" location="f0:73" file="f0" line="73"/>
    <Argument type="_145" location="f0:73" file="f0" line="73"/>
  </Function>
  <Function id="_68" name="__builtin_powil" returns="_143" context="_1" location="f0:74" file="f0" line="74" extern="1" attributes="nothrow pure no vops">
    <Argument type="_143" location="f0:74" file="f0" line="74"/>
    <Argument type="_145" location="f0:74" file="f0" line="74"/>
  </Function>
  <Function id="_69" name="__builtin_modff" returns="_142" context="_1" mangled="modff" location="f0:68" file="f0" line="68" extern="1" attributes="nothrow">
    <Argument type="_142" location="f0:68" file="f0" line="68"/>
    <Argument type="_170" location="f0:68" file="f0" line="68"/>
  </Function>
  <Function id="_70" name="__builtin_exp" returns="_140" context="_1" mangled="exp" location="f0:45" file="f0" line="45" extern="1" attributes="nothrow">
    <Argument type="_140" location="f0:45" file="f0" line="45"/>
  </Function>
  <Function id="_71" name="__builtin_modfl" returns="_143" context="_1" mangled="modfl" location="f0:69" file="f0" line="69" extern="1" attributes="nothrow">
    <Argument type="_143" location="f0:69" file="f0" line="69"/>
    <Argument type="_171" location="f0:69" file="f0" line="69"/>
  </Function>
  <Function id="_72" name="__builtin_prefetch" returns="_150" context="_1" location="f0:17" file="f0" line="17" extern="1" attributes="no vops">
    <Argument name="ADDR" type="_152" location="f0:17" file="f0" line="17"/>
    <Ellipsis/>
  </Function>
  <Function id="_73" name="__builtin_tan" returns="_140" context="_1" mangled="tan" location="f0:84" file="f0" line="84" extern="1" attributes="nothrow pure no vops">
    <Argument type="_140" location="f0:84" file="f0" line="84"/>
  </Function>
  <Function id="_74" name="__builtin_fabsf" returns="_142" context="_1" mangled="fabsf" location="f0:49" file="f0" line="49" extern="1" attributes="nothrow const">
    <Argument type="_142" location="f0:49" file="f0" line="49"/>
  </Function>
  <Function id="_75" name="__builtin_fabsl" returns="_143" context="_1" mangled="fabsl" location="f0:50" file="f0" line="50" extern="1" attributes="nothrow const">
    <Argument type="_143" location="f0:50" file="f0" line="50"/>
  </Function>
  <Function id="_76" name="__builtin_inf" returns="_140" context="_1" location="f0:18" file="f0" line="18" extern="1" attributes="nothrow const"/>
  <Namespace id="_77" name="__cxxabiv1" context="_1" members="" mangled="_Z10__cxxabiv1" demangled="__cxxabiv1"/>
  <Function id="_78" name="__builtin_frame_address" returns="_151" context="_1" location="f0:15" file="f0" line="15" extern="1">
    <Argument name="LEVEL" type="_153" location="f0:15" file="f0" line="15"/>
  </Function>
  <Function id="_79" name="__builtin_cabs" returns="_140" context="_1" mangled="cabs" location="f0:91" file="f0" line="91" extern="1" attributes="nothrow pure no vops">
    <Argument type="_149" location="f0:91" file="f0" line="91"/>
  </Function>
  <Function id="_80" name="__builtin_atan2f" returns="_142" context="_1" mangled="atan2f" location="f0:32" file="f0" line="32" extern="1" attributes="nothrow">
    <Argument type="_142" location="f0:32" file="f0" line="32"/>
    <Argument type="_142" location="f0:32" file="f0" line="32"/>
  </Function>
  <Function id="_81" name="__builtin_atan2l" returns="_143" context="_1" mangled="atan2l" location="f0:33" file="f0" line="33" extern="1" attributes="nothrow">
    <Argument type="_143" location="f0:33" file="f0" line="33"/>
    <Argument type="_143" location="f0:33" file="f0" line="33"/>
  </Function>
  <Function id="_82" name="__builtin_isinf" returns="_144" context="_1" mangled="isinf" location="f0:139" file="f0" line="139" extern="1" attributes="nothrow const">
    <Ellipsis/>
  </Function>
  <Function id="_83" name="__builtin_fpclassify" returns="_144" context="_1" location="f0:135" file="f0" line="135" extern="1">
    <Ellipsis/>
  </Function>
  <Function id="_84" name="__builtin_ccoshf" returns="_147" context="_1" mangled="ccoshf" location="f0:105" file="f0" line="105" extern="1" attributes="nothrow pure no vops">
    <Argument type="_147" location="f0:105" file="f0" line="105"/>
  </Function>
  <Function id="_85" name="__builtin_ccoshl" returns="_148" context="_1" mangled="ccoshl" location="f0:107" file="f0" line="107" extern="1" attributes="nothrow pure no vops">
    <Argument type="_148" location="f0:107" file="f0" line="107"/>
  </Function>
  <Function id="_86" name="__builtin_atan" returns="_140" context="_1" mangled="atan" location="f0:30" file="f0" line="30" extern="1" attributes="nothrow pure no vops">
    <Argument type="_140" location="f0:30" file="f0" line="30"/>
  </Function>
  <Function id="_87" name="__builtin_sinhf" returns="_142" context="_1" mangled="sinhf" location="f0:78" file="f0" line="78" extern="1" attributes="nothrow">
    <Argument type="_142" location="f0:78" file="f0" line="78"/>
  </Function>
  <Function id="_88" name="__builtin_sinhl" returns="_143" context="_1" mangled="sinhl" location="f0:79" file="f0" line="79" extern="1" attributes="nothrow">
    <Argument type="_143" location="f0:79" file="f0" line="79"/>
  </Function>
  <Function id="_89" name="__builtin_sqrtf" returns="_142" context="_1" mangled="sqrtf" location="f0:82" file="f0" line="82" extern="1" attributes="nothrow">
    <Argument type="_142" location="f0:82" file="f0" line="82"/>
  </Function>
  <Function id="_90" name="__builtin_sqrtl" returns="_143" context="_1" mangled="sqrtl" location="f0:83" file="f0" line="83" extern="1" attributes="nothrow">
    <Argument type="_143" location="f0:83" file="f0" line="83"/>
  </Function>
  <Function id="_91" name="__builtin_frexpf" returns="_142" context="_1" mangled="frexpf" location="f0:57" file="f0" line="57" extern="1" attributes="nothrow">
    <Argument type="_142" location="f0:57" file="f0" line="57"/>
    <Argument type="_154" location="f0:57" file="f0" line="57"/>
  </Function>
  <Function id="_92" name="__builtin_frexpl" returns="_143" context="_1" mangled="frexpl" location="f0:58" file="f0" line="58" extern="1" attributes="nothrow">
    <Argument type="_143" location="f0:58" file="f0" line="58"/>
    <Argument type="_154" location="f0:58" file="f0" line="58"/>
  </Function>
  <Function id="_93" name="__builtin_cpowf" returns="_147" context="_1" mangled="cpowf" location="f0:129" file="f0" line="129" extern="1" attributes="nothrow pure no vops">
    <Argument type="_147" location="f0:129" file="f0" line="129"/>
    <Argument type="_147" location="f0:129" file="f0" line="129"/>
  </Function>
  <Function id="_94" name="__builtin_cpowl" returns="_148" context="_1" mangled="cpowl" location="f0:131" file="f0" line="131" extern="1" attributes="nothrow pure no vops">
    <Argument type="_148" location="f0:131" file="f0" line="131"/>
    <Argument type="_148" location="f0:131" file="f0" line="131"/>
  </Function>
  <Function id="_95" name="__builtin_tanhf" returns="_142" context="_1" mangled="tanhf" location="f0:87" file="f0" line="87" extern="1" attributes="nothrow pure no vops">
    <Argument type="_142" location="f0:87" file="f0" line="87"/>
  </Function>
  <Function id="_96" name="__builtin_tanhl" returns="_143" context="_1" mangled="tanhl" location="f0:88" file="f0" line="88" extern="1" attributes="nothrow pure no vops">
    <Argument type="_143" location="f0:88" file="f0" line="88"/>
  </Function>
  <Function id="_97" name="__builtin_cabsf" returns="_142" context="_1" mangled="cabsf" location="f0:90" file="f0" line="90" extern="1" attributes="nothrow pure no vops">
    <Argument type="_147" location="f0:90" file="f0" line="90"/>
  </Function>
  <Function id="_98" name="__builtin_cabsl" returns="_143" context="_1" mangled="cabsl" location="f0:92" file="f0" line="92" extern="1" attributes="nothrow pure no vops">
    <Argument type="_148" location="f0:92" file="f0" line="92"/>
  </Function>
  <Function id="_99" name="__builtin_powf" returns="_142" context="_1" mangled="powf" location="f0:70" file="f0" line="70" extern="1" attributes="nothrow">
    <Argument type="_142" location="f0:70" file="f0" line="70"/>
    <Argument type="_142" location="f0:70" file="f0" line="70"/>
  </Function>
  <Function id="_100" name="__builtin_powi" returns="_140" context="_1" location="f0:72" file="f0" line="72" extern="1" attributes="nothrow pure no vops">
    <Argument type="_140" location="f0:72" file="f0" line="72"/>
    <Argument type="_145" location="f0:72" file="f0" line="72"/>
  </Function>
  <Function id="_101" name="__builtin_powl" returns="_143" context="_1" mangled="powl" location="f0:71" file="f0" line="71" extern="1" attributes="nothrow">
    <Argument type="_143" location="f0:71" file="f0" line="71"/>
    <Argument type="_143" location="f0:71" file="f0" line="71"/>
  </Function>
  <Function id="_102" name="__builtin_ccos" returns="_149" context="_1" mangled="ccos" location="f0:103" file="f0" line="103" extern="1" attributes="nothrow pure no vops">
    <Argument type="_149" location="f0:103" file="f0" line="103"/>
  </Function>
  <Function id="_103" name="__builtin_expect" returns="_169" context="_1" location="f0:16" file="f0" line="16" extern="1" attributes="nothrow const">
    <Argument name="EXP" type="_169" location="f0:16" file="f0" line="16"/>
    <Argument name="C" type="_169" location="f0:16" file="f0" line="16"/>
  </Function>
  <Function id="_104" name="__builtin_popcountl" returns="_145" context="_1" location="f0:100" file="f0" line="100" extern="1" attributes="nothrow const">
    <Argument type="_169" location="f0:100" file="f0" line="100"/>
  </Function>
  <Function id="_105" name="__builtin_inff" returns="_142" context="_1" location="f0:19" file="f0" line="19" extern="1" attributes="nothrow const"/>
  <Function id="_106" name="__builtin_infl" returns="_143" context="_1" location="f0:20" file="f0" line="20" extern="1" attributes="nothrow const"/>
  <Function id="_107" name="__builtin_cos" returns="_140" context="_1" mangled="cos" location="f0:39" file="f0" line="39" extern="1" attributes="nothrow pure no vops">
    <Argument type="_140" location="f0:39" file="f0" line="39"/>
  </Function>
  <Function id="_108" name="__builtin_ctz" returns="_145" context="_1" location="f0:96" file="f0" line="96" extern="1" attributes="nothrow const">
    <Argument type="_145" location="f0:96" file="f0" line="96"/>
  </Function>
  <Function id="_109" name="__builtin_return_address" returns="_151" context="_1" location="f0:14" file="f0" line="14" extern="1">
    <Argument name="LEVEL" type="_153" location="f0:14" file="f0" line="14"/>
  </Function>
  <Function id="_110" name="__builtin_isnan" returns="_144" context="_1" mangled="isnan" location="f0:144" file="f0" line="144" extern="1" attributes="nothrow const">
    <Ellipsis/>
  </Function>
  <Function id="_111" name="__builtin_csinhf" returns="_147" context="_1" mangled="csinhf" location="f0:117" file="f0" line="117" extern="1" attributes="nothrow pure no vops">
    <Argument type="_147" location="f0:117" file="f0" line="117"/>
  </Function>
  <Function id="_112" name="__builtin_csinhl" returns="_148" context="_1" mangled="csinhl" location="f0:119" file="f0" line="119" extern="1" attributes="nothrow pure no vops">
    <Argument type="_148" location="f0:119" file="f0" line="119"/>
  </Function>
  <Function id="_113" name="__builtin_csqrtf" returns="_147" context="_1" mangled="csqrtf" location="f0:120" file="f0" line="120" extern="1" attributes="nothrow pure no vops">
    <Argument type="_147" location="f0:120" file="f0" line="120"/>
  </Function>
  <Function id="_114" name="__builtin_csqrtl" returns="_148" context="_1" mangled="csqrtl" location="f0:122" file="f0" line="122" extern="1" attributes="nothrow pure no vops">
    <Argument type="_148" location="f0:122" file="f0" line="122"/>
  </Function>
  <Function id="_115" name="__builtin_floor" returns="_140" context="_1" mangled="floor" location="f0:51" file="f0" line="51" extern="1" attributes="nothrow const">
    <Argument type="_140" location="f0:51" file="f0" line="51"/>
  </Function>
  <Function id="_116" name="__builtin_ldexp" returns="_140" context="_1" mangled="ldexp" location="f0:59" file="f0" line="59" extern="1" attributes="nothrow">
    <Argument type="_140" location="f0:59" file="f0" line="59"/>
    <Argument type="_145" location="f0:59" file="f0" line="59"/>
  </Function>
  <Function id="_117" name="__builtin_ccosf" returns="_147" context="_1" mangled="ccosf" location="f0:102" file="f0" line="102" extern="1" attributes="nothrow pure no vops">
    <Argument type="_147" location="f0:102" file="f0" line="102"/>
  </Function>
  <Function id="_118" name="__builtin_ccosh" returns="_149" context="_1" mangled="ccosh" location="f0:106" file="f0" line="106" extern="1" attributes="nothrow pure no vops">
    <Argument type="_149" location="f0:106" file="f0" line="106"/>
  </Function>
  <Function id="_119" name="__builtin_ccosl" returns="_148" context="_1" mangled="ccosl" location="f0:104" file="f0" line="104" extern="1" attributes="nothrow pure no vops">
    <Argument type="_148" location="f0:104" file="f0" line="104"/>
  </Function>
  <Function id="_120" name="__builtin_islessgreater" returns="_144" context="_1" location="f0:143" file="f0" line="143" extern="1" attributes="nothrow const">
    <Ellipsis/>
  </Function>
  <Function id="_121" name="__builtin_ctanhf" returns="_147" context="_1" mangled="ctanhf" location="f0:126" file="f0" line="126" extern="1" attributes="nothrow pure no vops">
    <Argument type="_147" location="f0:126" file="f0" line="126"/>
  </Function>
  <Function id="_122" name="__builtin_ctanhl" returns="_148" context="_1" mangled="ctanhl" location="f0:128" file="f0" line="128" extern="1" attributes="nothrow pure no vops">
    <Argument type="_148" location="f0:128" file="f0" line="128"/>
  </Function>
  <Function id="_123" name="__builtin_ceilf" returns="_142" context="_1" mangled="ceilf" location="f0:37" file="f0" line="37" extern="1" attributes="nothrow const">
    <Argument type="_142" location="f0:37" file="f0" line="37"/>
  </Function>
  <Function id="_124" name="__builtin_ceill" returns="_143" context="_1" mangled="ceill" location="f0:38" file="f0" line="38" extern="1" attributes="nothrow const">
    <Argument type="_143" location="f0:38" file="f0" line="38"/>
  </Function>
  <Function id="_125" name="__builtin_csinf" returns="_147" context="_1" mangled="csinf" location="f0:114" file="f0" line="114" extern="1" attributes="nothrow pure no vops">
    <Argument type="_147" location="f0:114" file="f0" line="114"/>
  </Function>
  <Function id="_126" name="__builtin_csinh" returns="_149" context="_1" mangled="csinh" location="f0:118" file="f0" line="118" extern="1" attributes="nothrow pure no vops">
    <Argument type="_149" location="f0:118" file="f0" line="118"/>
  </Function>
  <Function id="_127" name="__builtin_csinl" returns="_148" context="_1" mangled="csinl" location="f0:116" file="f0" line="116" extern="1" attributes="nothrow pure no vops">
    <Argument type="_148" location="f0:116" file="f0" line="116"/>
  </Function>
  <Function id="_128" name="__builtin_acos" returns="_140" context="_1" mangled="acos" location="f0:24" file="f0" line="24" extern="1" attributes="nothrow">
    <Argument type="_140" location="f0:24" file="f0" line="24"/>
  </Function>
  <Function id="_129" name="__builtin_ctzll" returns="_145" context="_1" location="f0:98" file="f0" line="98" extern="1" attributes="nothrow const">
    <Argument type="_146" location="f0:98" file="f0" line="98"/>
  </Function>
  <Function id="_130" name="__builtin_cargf" returns="_142" context="_1" mangled="cargf" location="f0:93" file="f0" line="93" extern="1" attributes="nothrow pure no vops">
    <Argument type="_147" location="f0:93" file="f0" line="93"/>
  </Function>
  <Function id="_131" name="__builtin_cargl" returns="_143" context="_1" mangled="cargl" location="f0:95" file="f0" line="95" extern="1" attributes="nothrow pure no vops">
    <Argument type="_148" location="f0:95" file="f0" line="95"/>
  </Function>
  <Function id="_132" name="__builtin_cosf" returns="_142" context="_1" mangled="cosf" location="f0:40" file="f0" line="40" extern="1" attributes="nothrow pure no vops">
    <Argument type="_142" location="f0:40" file="f0" line="40"/>
  </Function>
  <Function id="_133" name="__builtin_cosh" returns="_140" context="_1" mangled="cosh" location="f0:41" file="f0" line="41" extern="1" attributes="nothrow">
    <Argument type="_140" location="f0:41" file="f0" line="41"/>
  </Function>
  <Function id="_134" name="__builtin_cosl" returns="_143" context="_1" mangled="cosl" location="f0:44" file="f0" line="44" extern="1" attributes="nothrow pure no vops">
    <Argument type="_143" location="f0:44" file="f0" line="44"/>
  </Function>
  <Function id="_135" name="__builtin_isgreater" returns="_144" context="_1" location="f0:137" file="f0" line="137" extern="1" attributes="nothrow const">
    <Ellipsis/>
  </Function>
  <Function id="_136" name="__builtin_sinf" returns="_142" context="_1" mangled="sinf" location="f0:76" file="f0" line="76" extern="1" attributes="nothrow pure no vops">
    <Argument type="_142" location="f0:76" file="f0" line="76"/>
  </Function>
  <Function id="_137" name="__builtin_sinh" returns="_140" context="_1" mangled="sinh" location="f0:77" file="f0" line="77" extern="1" attributes="nothrow">
    <Argument type="_140" location="f0:77" file="f0" line="77"/>
  </Function>
  <Function id="_138" name="__builtin_sinl" returns="_143" context="_1" mangled="sinl" location="f0:80" file="f0" line="80" extern="1" attributes="nothrow pure no vops">
    <Argument type="_143" location="f0:80" file="f0" line="80"/>
  </Function>
  <Function id="_139" name="__builtin_csin" returns="_149" context="_1" mangled="csin" location="f0:115" file="f0" line="115" extern="1" attributes="nothrow pure no vops">
    <Argument type="_149" location="f0:115" file="f0" line="115"/>
  </Function>
  <FundamentalType id="_140" name="double" size="64" align="64"/>
  <PointerType id="_141" type="_172c" size="32" align="32"/>
  <FundamentalType id="_142" name="float" size="32" align="32"/>
  <FundamentalType id="_143" name="long double" size="96" align="32"/>
  <FundamentalType id="_144" name="bool" size="8" align="8"/>
  <FundamentalType id="_145" name="int" size="32" align="32"/>
  <FundamentalType id="_146" name="long long int" size="64" align="64"/>
  <FundamentalType id="_147" name="complex float" size="64" align="32"/>
  <FundamentalType id="_148" name="complex long double" size="192" align="32"/>
  <FundamentalType id="_149" name="complex double" size="128" align="64"/>
  <FundamentalType id="_150" name="void" align="8"/>
  <PointerType id="_151" type="_150" size="32" align="32"/>
  <PointerType id="_152" type="_150c" size="32" align="32"/>
  <FundamentalType id="_153" name="unsigned int" size="32" align="32"/>
  <PointerType id="_154" type="_145" size="32" align="32"/>
  <Destructor id="_155" name="type1" artificial="1" throw="" context="_61" access="public" mangled="_ZN5type1D1Ev *INTERNAL* " demangled="type1::~type1()" location="f1:2" file="f1" line="2" endline="2" inline="1">
  </Destructor>
  <OperatorMethod id="_156" name="=" returns="_175" artificial="1" throw="" context="_61" access="public" mangled="_ZN5type1aSERKS_" demangled="type1::operator=(type1 const&amp;)" location="f1:2" file="f1" line="2" endline="2" inline="1">
    <Argument type="_176" location="f1:2" file="f1" line="2"/>
  </OperatorMethod>
  <Constructor id="_157" name="type1" artificial="1" throw="" context="_61" access="public" mangled="_ZN5type1C1ERKS_ *INTERNAL* " demangled="type1::type1(type1 const&amp;)" location="f1:2" file="f1" line="2" inline="1">
    <Argument type="_176" location="f1:2" file="f1" line="2"/>
  </Constructor>
  <Constructor id="_158" name="type1" artificial="1" throw="" context="_61" access="public" mangled="_ZN5type1C1Ev *INTERNAL* " demangled="type1::type1()" location="f1:2" file="f1" line="2" inline="1"/>
  <Field id="_159" name="x" type="_145" offset="0" context="_62" access="public" location="f1:6" file="f1" line="6"/>
  <Destructor id="_160" name="type2" artificial="1" throw="" context="_62" access="public" mangled="_ZN5type2D1Ev *INTERNAL* " demangled="type2::~type2()" location="f1:5" file="f1" line="5" endline="5" inline="1">
  </Destructor>
  <OperatorMethod id="_161" name="=" returns="_177" artificial="1" throw="" context="_62" access="public" mangled="_ZN5type2aSERKS_" demangled="type2::operator=(type2 const&amp;)" location="f1:5" file="f1" line="5" endline="5" inline="1">
    <Argument type="_178" location="f1:5" file="f1" line="5"/>
  </OperatorMethod>
  <Constructor id="_162" name="type2" artificial="1" throw="" context="_62" access="public" mangled="_ZN5type2C1ERKS_ *INTERNAL* " demangled="type2::type2(type2 const&amp;)" location="f1:5" file="f1" line="5" endline="5" inline="1">
    <Argument type="_178" location="f1:5" file="f1" line="5"/>
  </Constructor>
  <Constructor id="_163" name="type2" artificial="1" throw="" context="_62" access="public" mangled="_ZN5type2C1Ev *INTERNAL* " demangled="type2::type2()" location="f1:5" file="f1" line="5" inline="1"/>
  <Field id="_164" name="y" type="_145" offset="32" context="_63" access="public" location="f1:10" file="f1" line="10"/>
  <Destructor id="_165" name="type3" artificial="1" throw="" context="_63" access="public" mangled="_ZN5type3D1Ev *INTERNAL* " demangled="type3::~type3()" location="f1:9" file="f1" line="9" endline="9" inline="1">
  </Destructor>
  <OperatorMethod id="_166" name="=" returns="_179" artificial="1" throw="" context="_63" access="public" mangled="_ZN5type3aSERKS_" demangled="type3::operator=(type3 const&amp;)" location="f1:9" file="f1" line="9" endline="9" inline="1">
    <Argument type="_180" location="f1:9" file="f1" line="9"/>
  </OperatorMethod>
  <Constructor id="_167" name="type3" artificial="1" throw="" context="_63" access="public" mangled="_ZN5type3C1ERKS_ *INTERNAL* " demangled="type3::type3(type3 const&amp;)" location="f1:9" file="f1" line="9" endline="9" inline="1">
    <Argument type="_180" location="f1:9" file="f1" line="9"/>
  </Constructor>
  <Constructor id="_168" name="type3" artificial="1" throw="" context="_63" access="public" mangled="_ZN5type3C1Ev *INTERNAL* " demangled="type3::type3()" location="f1:9" file="f1" line="9" endline="9" inline="1"/>
  <FundamentalType id="_169" name="long int" size="32" align="32"/>
  <PointerType id="_170" type="_142" size="32" align="32"/>
  <PointerType id="_171" type="_143" size="32" align="32"/>
  <ReferenceType id="_175" type="_61" size="32" align="32"/>
  <ReferenceType id="_176" type="_61c" size="32" align="32"/>
  <ReferenceType id="_177" type="_62" size="32" align="32"/>
  <ReferenceType id="_178" type="_62c" size="32" align="32"/>
  <ReferenceType id="_179" type="_63" size="32" align="32"/>
  <ReferenceType id="_180" type="_63c" size="32" align="32"/>
  <FundamentalType id="_172" name="char" size="8" align="8"/>
  <CvQualifiedType id="_172c" type="_172" const="1"/>
  <CvQualifiedType id="_150c" type="_150" const="1"/>
  <CvQualifiedType id="_61c" type="_61" const="1"/>
  <CvQualifiedType id="_62c" type="_62" const="1"/>
  <CvQualifiedType id="_63c" type="_63" const="1"/>
  <File id="f0" name="/usr/share/gccxml-0.9/GCC/4.5/gccxml_builtins.h"/>
  <File id="f1" name="main1.cpp"/>
</GCC_XML>


многое не понятно. но члены вижу. нужно в доку посерьезней глянуть.

Добавлено через 1 минуту и 9 секунд
начало xml вырезал, а то форум ругался. там были только builtin функции/типы/переменные.

Добавлено через 2 минуты и 35 секунд
Цитата(xvr @  24.7.2011,  16:11 Найти цитируемый пост)
парсить отладочную информацию (DWARF2 например)

по моему, поздно что-то генерить в код, когда уже сгенерина отладочная инфа. или предлагаете двойной проход?

Добавлено через 5 минут и 39 секунд
и при использовании gcc-xml, выходной файл придется скармливать кодогенератору, я Вас правильно понял?
при использовании плагинов же, код можно обрабатывать и генерировать тем же плагином. ну или разделить парсер и генератор на два плагина.
PM WWW   Вверх
boostcoder
Дата 24.7.2011, 17:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



еще хочется интроспекции типа такой:
Код

__attribute__(("introspection_get_var", t))->method(); // получить переменную c именем t и вызвать метод.


вроде как согласно манам, это возможно. буду пробовать.

Добавлено @ 17:20
вот только нужно решить что удобней, аттрибуты или прагмы... согласно докам, обработка аттрибутов и прагм ничем не отличается. т.е. обработчики получают одинаковую инфу о контексте.

Это сообщение отредактировал(а) boostcoder - 24.7.2011, 18:12
PM WWW   Вверх
boostcoder
Дата 24.7.2011, 18:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(boostcoder @  24.7.2011,  17:19 Найти цитируемый пост)
своеобразный аналог auto

глупая идея. исключить smile
PM WWW   Вверх
xvr
Дата 24.7.2011, 18:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(boostcoder @  24.7.2011,  16:24 Найти цитируемый пост)
по моему, поздно что-то генерить в код, когда уже сгенерина отладочная инфа. или предлагаете двойной проход?

Угу
Цитата(boostcoder @  24.7.2011,  16:24 Найти цитируемый пост)
и при использовании gcc-xml, выходной файл придется скармливать кодогенератору, я Вас правильно понял?

Да

Цитата(boostcoder @  24.7.2011,  16:24 Найти цитируемый пост)
при использовании плагинов же, код можно обрабатывать и генерировать тем же плагином. ну или разделить парсер и генератор на два плагина. 

Да, это явный плюс. В принципе такой плагин можно сделать на основе того же gcc-xml, а можно и не на основе  smile 
PM MAIL   Вверх
boostcoder
Дата 24.7.2011, 18:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(xvr @  24.7.2011,  18:32 Найти цитируемый пост)
такой плагин можно сделать на основе того же gcc-xml

по моему нет. gcc-xml это пропатченный gcc. т.е. и плагинами там и не пахнет. а разбирать его код ой как сложно smile

Добавлено через 2 минуты и 19 секунд
Цитата(boostcoder @  24.7.2011,  16:24 Найти цитируемый пост)
или разделить парсер и генератор на два плагина

кстати дочитал до того места, где объясняется как плагины могут "общаться" между собой.
PM WWW   Вверх
boostcoder
Дата 24.7.2011, 19:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(boostcoder @  24.7.2011,  17:19 Найти цитируемый пост)
// получить переменную c именем t и вызвать метод.

тут, я думаю нужно получать ближайшую в скопе переменную с этим именем.
или как?

конечно, знание ЯП с нормальной introspection очень помогло бы в понимании...
PM WWW   Вверх
xvr
Дата 24.7.2011, 19:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(boostcoder @  24.7.2011,  19:14 Найти цитируемый пост)
конечно, знание ЯП с нормальной introspection очень помогло бы в понимании... 

Я знаю их не так много (точнее совсем почти не знаю), но в Java например это сделано отдельным пакетом (java.lang.reflect). В VCL это сделано так же отдельным классом, описывающим тип. Возможно, что и тут имеет смысл сделать нечто, расширяющее RTTI.  smile 

PM MAIL   Вверх
boostcoder
Дата 24.7.2011, 19:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(xvr @  24.7.2011,  19:20 Найти цитируемый пост)
нечто, расширяющее RTTI

например что/как и что желательно получить в итоге?

Добавлено через 3 минуты и 24 секунды
xvr, говорю же: мне, конкретно для моей задачи необходимы два момента:
1. генерация сериализаторов/десериализаторов.
2. reflection с возможностью указать куда и как рефлектиться. т.е. - сериализатор, БД, другой объект этого же типа.

но возможно в других ЯП есть более разумные и удобные моменты о которых я просто не знаю...
PM WWW   Вверх
kosmonaFFFt
Дата 25.7.2011, 06:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 538
Регистрация: 14.4.2008
Где: Иннополис

Репутация: нет
Всего: 5



Цитата(boostcoder @  24.7.2011,  23:23 Найти цитируемый пост)
но возможно в других ЯП есть более разумные и удобные моменты о которых я просто не знаю...


Погляди в Java, там есть класс Class, описывающий классы, экземпляр которого можно получить например так:
Код

Class c = MyClass.class;

а из него можно получить всю информацию, например методы, поля, суперклассы и т. д...


--------------------
user posted image
PM MAIL ICQ   Вверх
boostcoder
Дата 25.7.2011, 07:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(kosmonaFFFt @  25.7.2011,  06:51 Найти цитируемый пост)
из него можно получить всю информацию, например методы, поля, суперклассы и т. д.

спасибо. гляну.
PM WWW   Вверх
xvr
Дата 25.7.2011, 17:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(boostcoder @  24.7.2011,  19:23 Найти цитируемый пост)
например что/как и что желательно получить в итоге?
  •  Описатель структуры класса: все поля, методы. Включая их тип, сигнатуру параметров (для методов) и пр. Вот только не инстанциированные шаблоны так не получишь (и видимо вообще не получишь)
  •  Метод для создания экземпляра класса
  •  Метод для получения этого самого расширенного RTTI (в виде класса) по имени типа (в виде строки или идентификатора) или из существующего экземпляра объекта

PM MAIL   Вверх
boostcoder
Дата 26.7.2011, 03:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(xvr @  25.7.2011,  17:07 Найти цитируемый пост)
Описатель структуры класса: все поля, методы. Включая их тип, сигнатуру параметров (для методов) и пр.

осталось понять как это должно выглядеть в коде smile

Цитата(xvr @  25.7.2011,  17:07 Найти цитируемый пост)
Метод для создания экземпляра класса

метод, или способ? тот же вопрос: как это должно выглядеть в коде?

Цитата(xvr @  25.7.2011,  17:07 Найти цитируемый пост)
Метод для получения этого самого расширенного RTTI (в виде класса)

т.е. _этот_расширенный_RTTI_ - это должен быть некий тип/класс?

Цитата(xvr @  25.7.2011,  17:07 Найти цитируемый пост)
по имени типа (в виде строки или идентификатора) или из существующего экземпляра объекта

и снова тот же вопрос: как это должно выглядеть в коде?


PM WWW   Вверх
kosmonaFFFt
Дата 26.7.2011, 07:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 538
Регистрация: 14.4.2008
Где: Иннополис

Репутация: нет
Всего: 5



Цитата(boostcoder @  26.7.2011,  07:36 Найти цитируемый пост)
и снова тот же вопрос: как это должно выглядеть в коде?


Например так:
Код

Class myClass = MyClass.class; // или Class myClass = Class.byName("MyClass");
void* myObj = myClass.newInstance();


К сожалению в С++ нету базового класса похожего на Object в Java, поэтому единственный на мой взгляд способ вернуть новый экземпляр класса, созданный через reflection - вернуть void*.


--------------------
user posted image
PM MAIL ICQ   Вверх
boostcoder
Дата 26.7.2011, 07:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Код

Class myClass = MyClass.class;

тут Class это кто? какая-то встроенная сущность?
а MyClass кто?
и в общем, что выполняется в этой строке?

PM WWW   Вверх
boostcoder
Дата 26.7.2011, 08:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



итак. с чем разобрался:
1. для каждой единицы трансляции формируется Abstract syntax tree.
2. реальный компилятор(cc1plus) обрабатывает только по одному файлу за раз. при передаче g++ нескольких файлов, он поочередно выполняет cc1plus для каждого файла. а значит плагин будет запускаться столько же раз, сколько файлов.
3. есть возможность навесить свой обработчик на: 1) окончание разбора единицы трансляции, 2) глобальную обработку прагм, 3) глобальную обработку атрибутов.
4. плагин может добавлять/удалять в базу стандартных прагм и атрибутов свои прагмы и атрибуты.
5. есть возможность навесить обработчик на какую-то конкретную прагму или атрибут. т.е. сначала регаем имя, потом вешаем свой обработчик на реганное имя.
6. нет возможности навесить обработчик на разбор деклараций :( хотя в инете есть патч для этого.
7. нет возможности влиять на синтаксис языка.
8. AST можно генерить/изменять/удалять. т.е. при изменении AST можно с кодом сделать все что угодно.

далее...

Это сообщение отредактировал(а) boostcoder - 26.7.2011, 09:47
PM WWW   Вверх
EnergoHokum
Дата 26.7.2011, 09:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 600
Регистрация: 10.11.2006
Где: Россия, Ставропол ь

Репутация: нет
Всего: 6



PM MAIL ICQ   Вверх
mes
Дата 26.7.2011, 09:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  26.7.2011,  06:36 Найти цитируемый пост)
тут Class это кто? какая-то встроенная сущность?
а MyClass кто?
и в общем, что выполняется в этой строке?

условно :
Class - type_info
MyClass - struct MyClass
MyClass.class - typeid(MyClass)

но применительно не для всех типов, а только для полиморфных.. что позволяет после создания объекта имея ссылку на класс динамически кастовать его к нужному интерфейсу.. 




--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 26.7.2011, 09:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



EnergoHokum, нет нужды smile

mes, а можете показать то же самое ,но в виде примера на с++? ;) т.е. каким вы видите использование, и какие дополнительные возможности должен предоставлять этот самый расширенный type_info?

Добавлено через 1 минуту
и да, type_info и typeid() никогда не использовал smile 
PM WWW   Вверх
boostcoder
Дата 26.7.2011, 09:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(boostcoder @  26.7.2011,  09:08 Найти цитируемый пост)
и да, type_info и typeid() никогда не использовал

это я к тому, что не очень представляю для чего они нужны, и как их использовать.
PM WWW   Вверх
mes
Дата 26.7.2011, 09:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  26.7.2011,  08:08 Найти цитируемый пост)
 а можете показать то же самое ,но в виде примера на с++? 

вот на скорую руку : http://liveworkspace.org/code/1e9029d8cabe...e9920a195e3336a


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 26.7.2011, 09:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



не понимаю... smile

Добавлено через 6 минут и 52 секунды
mes, т.е. смысл в том, чтоб объект мог создать объект своего же типа? а как это можно использовать?
еще не понял что Вы хотели продемонстрировать с помощью dynamic_cast?
PM WWW   Вверх
mes
Дата 26.7.2011, 10:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  26.7.2011,  08:46 Найти цитируемый пост)
т.е. смысл в том, чтоб объект мог создать объект своего же типа? 

нет в том, что объектом не является не только инстанция класса, но и сам класс.. какими возможностями будет обладать объект-класс зависит от идеологии.. 

Цитата(boostcoder @  26.7.2011,  08:46 Найти цитируемый пост)
 Вы хотели продемонстрировать с помощью dynamic_cast

в рантайме мы можем создать только безличностный объект, а dynamic_cast показываеткак привести к нужному интерфейсу smile

Добавлено через 1 минуту и 39 секунд
мой пример был приведен не по теме, а  как ответ на 
Цитата(boostcoder @  26.7.2011,  06:36 Найти цитируемый пост)
и в общем, что выполняется в этой строке?


Добавлено через 5 минут и 37 секунд
если ближе к теме, то кусок должен выглядить так :
Код

type  const& _type = get_class("A");
object *obj = _type.create();


Добавлено через 7 минут и 50 секунд
P.S. и вместо type по смыслу больше подходит Class..


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 26.7.2011, 10:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  26.7.2011,  10:37 Найти цитируемый пост)
нет в том, что объектом не является не только инстанция класса, но и сам класс.

все равно не понял..
можете как-то псевдокодом показать пример того как это дело можно использовать... и для чего? ;)

Добавлено через 3 минуты и 52 секунды
я не понимаю я этого, наверное потому что никогда не писал на ЯП которые это умеют делать smile
PM WWW   Вверх
xvr
Дата 26.7.2011, 10:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(boostcoder @  26.7.2011,  08:49 Найти цитируемый пост)
3. есть возможность навесить свой обработчик на: 1) окончание разбора единицы трансляции,

Вешать сюда. По AST со входа нужно генерить таблицы с расширенным RTTI (RTTIEx), и специальный сегмент для общей таблицы с именами типов и ссылками на RTTIEx для каждого типа.

Цитата(boostcoder @  26.7.2011,  07:36 Найти цитируемый пост)
тут Class это кто?

Это вторая часть reflection - специальная библиотека. Этот Class использует таблицы RTTIEx для выдачи энумераторов на все member'ы класса. Каждый экземпляр Class описывает один конкретный тип

Кроме энумераторов Class должен содержать функции для чтения/записи/вызова member'ов исходного класса и функцию для создания этих самых исходных классов.

Конкретные интерфейсы написать прямо тут затрудняюсь - их слишком много

PM MAIL   Вверх
boostcoder
Дата 26.7.2011, 10:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  26.7.2011,  10:37 Найти цитируемый пост)
type const& _type = get_class("A");

тут type - какой-то базовый тип?
т.е. таким образом мы можем получить объект базового типа который умеет создавать объекты типа "A" ?
PM WWW   Вверх
mes
Дата 26.7.2011, 11:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  26.7.2011,  09:57 Найти цитируемый пост)
т.е. таким образом мы можем получить объект базового типа который умеет создавать объекты типа "A" 

таким образом мы получаем объект (объект-тип), который знает "все" о классе типа "А"  , а также может создатьинстанцию этого класса.. 
P.S. к базовым классам типа A отношение не имеет, это отдельная линия.. 




--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 26.7.2011, 11:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(xvr @  26.7.2011,  10:55 Найти цитируемый пост)
Вешать сюда.

но в таком случае, дополнительный код будет генериться для всех классовых типов. разве это нужно?
я представлял что прогер сам помечает класс при помощи прагм или атрибутов. и для этих типов и будет генериться все необходимое..

Цитата(xvr @  26.7.2011,  10:55 Найти цитируемый пост)
По AST со входа нужно генерить таблицы с расширенным RTTI (RTTIEx), и специальный сегмент для общей таблицы с именами типов и ссылками на RTTIEx для каждого типа.

очень желательно это объяснить в боооолее развернутой форме. ибо я никогда не разрабатывал/модифицировал компиляторы. и мне еще многое не понятно smile

Цитата(xvr @  26.7.2011,  10:55 Найти цитируемый пост)
Это вторая часть reflection - специальная библиотека. Этот Class использует таблицы RTTIEx для выдачи энумераторов на все member'ы класса. Каждый экземпляр Class описывает один конкретный тип

с этим понятно. вроде...

Цитата(xvr @  26.7.2011,  10:55 Найти цитируемый пост)
Кроме энумераторов Class должен содержать функции для чтения/записи/вызова member'ов исходного класса и функцию для создания этих самых исходных классов.

тоже понятно...

Цитата(xvr @  26.7.2011,  10:55 Найти цитируемый пост)
Конкретные интерфейсы написать прямо тут затрудняюсь - их слишком много

чьи интерфейсы?
PM WWW   Вверх
mes
Дата 26.7.2011, 11:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  26.7.2011,  10:05 Найти цитируемый пост)
чьи интерфейсы? 

Цитата(xvr @  26.7.2011,  09:55 Найти цитируемый пост)
 функции для чтения/записи/вызова member'ов исходного класса и функцию для создания


Добавлено @ 11:22
вот еще пример 
Код

struct A { 
 published:
    Void fn(Int i, Double d) // где все аргументы наследники object
    {    }

};

fn(4, 4.5); // прямой вызов

// "безличностный вызов" : 
Args args;
args.push_back(Int(4));
args.push_back(Double(5));

std::string cls = "A";
Class classA = get_class(cls); 

object * obj  = classA.create ();
obj->invoke(classA.get_memfn("fn"), args);




Это сообщение отредактировал(а) mes - 26.7.2011, 11:48


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 26.7.2011, 11:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



mes, минутку... это нужно переварить..

Это сообщение отредактировал(а) boostcoder - 26.7.2011, 13:17
PM WWW   Вверх
boostcoder
Дата 26.7.2011, 12:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



к примеру, если имя типа/объекта известны во время компиляции в виде строки, то как создать объект или получить ссылку на существующий объект - понятно.
Код

// создание объекта по его имени.
obj = create("A"); // находим декларацию типа "A", и заменяем эту строку на это: A obj;

// далее, получение ссылки на объект.
ref = get("obj"); // находим переменную "obj", определяем ее тип, и вместо этой строки записываем это: A& ref = obj;

// вызов метода.
get("ref").invoke("method")(args);

тут все просто.

но для того чтоб интроспекция была динамической, нам нужно уметь выполнять все тоже самое но в рантайме... а для этого кодогенерация в компайлтайме не подходит...
т.е., все классовые типы должны наследовать базовый тип Class, к примеру...
Код

struct Class {
   Class* create(const char*) {} // это правильно?
   Class* invoke(const char*, ...) {} // а вот тут не понятно. invoke() должен возвращать значение.
              // вопрос: для возвращаемых/принимаемых значений должен быть какой-то базовый тип? или использовать тот же Class?
};



Это сообщение отредактировал(а) boostcoder - 26.7.2011, 13:24
PM WWW   Вверх
boostcoder
Дата 26.7.2011, 13:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



т.е. к примеру такая программа:
Код


struct type1 {
   int add(int a, int b) {return a+b;}
};

struct type2 {
   int mul(int a, int b) {return a+b;}
};

int main() {
   type1 t1;
   int r1 = t1.add(2, 2);
   type2 t2;
   int r2 = t2.mul(2, 2);
}



должна быть оттранслирована в нечто типа этого:
Код


struct Class {
   Class* create(const char*) {}
   Class* invoke(const char*, ...) {}
};

struct type1: Class {
   int add(int a, int b) {return a+b;}
};

struct type2: Class {
   int mul(int a, int b) {return a*b;}
};

int main() {
   Class* r1 = create("type1")->invoke("add", 2, 2);
   Class* r2 = create("type2")->invoke("mul", 2, 2);
}


правильно?

еще не понятно, как быть с объектами... create и invoke должны возвращать указатели?

и еще, будет ли такой код считаться логичным, и нужно ли оно вообще?
Код

   Class* obj1 = create("type1");
   Class* obj2 = obj1->create("type2");



Это сообщение отредактировал(а) boostcoder - 26.7.2011, 18:07
PM WWW   Вверх
kosmonaFFFt
Дата 26.7.2011, 14:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 538
Регистрация: 14.4.2008
Где: Иннополис

Репутация: нет
Всего: 5



Цитата(boostcoder @  26.7.2011,  16:13 Найти цитируемый пост)
но для того чтоб интроспекция была динамической, нам нужно уметь выполнять все тоже самое но в рантайме...


Чтобы это сделать, нужно при компиляции сгенерировать код, который для каждого класса в программе при ее запуске создаст объект типа Class (или type_info или как-нибуть еще) и положит его в какую-нибудь коллекцию (например в Java этим занимается ClassLoader виртуальной машины), чтобы можно было потом его в это коллекции найти, извлечь и использовать... Классы в программе не должны наследоваться от класса Class, для каждого класса должен быть создан объект класса Class, но желательно иметь что-то типа класса Object, от которого они бы наследовались... Ну или как-то так...

З.Ы. Все это взято мной из воспоминаний о том, как работает reflection в Java...


--------------------
user posted image
PM MAIL ICQ   Вверх
boostcoder
Дата 26.7.2011, 14:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



т.е. получается, что все объекты типа Class ссылаются на какую-то глобальную карту. и данные для этой карты нужно генерировать в компайлтайм. а инициализировать в рантайм? правильно мыслю?

Добавлено через 1 минуту и 36 секунд
kosmonaFFFt, можешь показать тоже самое в коде? или в псевдокоде.
PM WWW   Вверх
mes
Дата 26.7.2011, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  26.7.2011,  11:13 Найти цитируемый пост)
 // вопрос: для возвращаемых/принимаемых значений должен быть какой-то базовый тип? или использовать тот же Class?

все объекты, как принимаемые аргументы, так и возвращаемые, в том числе Void являются наследником Object..
просьба не путать типы Object и Class.. если первый является базой для всех полиморфных типов, то второй метаинформация о классе.. 
т.е. Class это такой объект с помощью которого можно создать наследника Object..

Добавлено через 2 минуты и 14 секунд
Цитата(boostcoder @  26.7.2011,  11:13 Найти цитируемый пост)
известны во время компиляции в виде строки

я приводил примеры по динамическому, потому как в статике и так все типы известны и никаких доп. ухищрений не надо.. 


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 26.7.2011, 15:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  26.7.2011,  15:44 Найти цитируемый пост)
просьба не путать типы Object и Class.. если первый является базой для всех полиморфных типов, то второй метаинформация о классе..

о! понял smile 

mes, а по остальным вопросам что-нибудь ответите? ;)

Добавлено через 1 минуту и 14 секунд
еще нужно решить что нужно в интерфейсах Class и Object...

и этот момент мне все еще не понятен -
Цитата(boostcoder @  26.7.2011,  13:50 Найти цитируемый пост)
еще не понятно, как быть с объектами... create и invoke должны возвращать указатели?


PM WWW   Вверх
mes
Дата 26.7.2011, 15:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



все принимают и возвращают объекты, а Void :
Код

struct Void : Object {} ;




--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 26.7.2011, 16:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  26.7.2011,  15:53 Найти цитируемый пост)
все принимают и возвращают объекты

а Class что возвращает?
PM WWW   Вверх
mes
Дата 26.7.2011, 16:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Class "умееет" создавать объект, знает его размер, может выдать енумерацию полей и функци, а возможно даже прикрепить нужную функцию.. smile




--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 26.7.2011, 16:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



mes, я себе это представлял так:
Код

struct Object {};

struct Value: Object {};
struct Void: Object {};

struct Char: Object {};
struct UChar: Object {};
struct Short: Object {};
struct UShort: Object {};
struct Int: Object {};
struct UInt: Object {};
struct Long: Object {};
struct ULong: Object {};
struct Int64: Object {};
struct UInt64: Object {};
struct Double: Object {};
struct Fload: Object {};
struct String: Object {};

struct Class: Object {};

 smile

Добавлено через 14 минут и 11 секунд
еще не уверен что нужны все эти типы:
Код


struct Char: Object {};
struct UChar: Object {};
struct Short: Object {};
struct UShort: Object {};
struct Int: Object {};
struct UInt: Object {};
struct Long: Object {};
struct ULong: Object {};
struct Int64: Object {};
struct UInt64: Object {};
struct Double: Object {};
struct Fload: Object {};
struct String: Object {};


может нужен только Value у которого должны быть методы для каста его внутреннего значения в нужный тип?

Это сообщение отредактировал(а) boostcoder - 26.7.2011, 16:29
PM WWW   Вверх
mes
Дата 26.7.2011, 16:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Class не состоит в иерархии Object`а.. грубо говоря он служит посредником между строковым именем и созданием объекта...



--------------------
PM MAIL WWW   Вверх
xvr
Дата 26.7.2011, 18:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



2 boostcoder: попробуйте представить часть описания типов из AST в виде иерархии классов - это и будет основа для интроспекции в RTTIEx (a-la Class, точнее его энумераторы)

Когда это более менее устаканится, можно будет переходить к проектированию 2й части интерфейсов Class'а - операции по модификации/вызовам через эти энумераторы

А уж к 3й части - созданию объектов, можно будет переходить когда первые 2 будут готовы.

Иначе у вас получится знатная каша, а не reflection  smile 

PM MAIL   Вверх
boostcoder
Дата 26.7.2011, 18:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(xvr @  26.7.2011,  18:00 Найти цитируемый пост)
попробуйте представить часть описания типов из AST в виде иерархии классов

а в более расширенной форме объяснить можете? ;)
PM WWW   Вверх
xvr
Дата 26.7.2011, 21:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(boostcoder @  26.7.2011,  18:23 Найти цитируемый пост)
а в более расширенной форме объяснить можете? ;) 

Я не знаю спецификацию AST из gcc поэтому точно написать не смогу. Но в общей форме, это должно быть как то так
Код

class Class {
public:
 class member_iterator; // *member_iterator => Member

 member_iterator members_begin();
 member_iterator members_end();
 .... все остальные методы, типа find и пр .........


 Class(const char*); // create from string ID
 Class(void*); // create from Object
};

class Member {
public:
 MemberType get_type();
 const char* get_name();
 size_t get_shift();
 void put_data(void*);
 void get_data(void*);
 void call_method(void* ret_val, std::vector<AnyValue>& args);
};


class MemberType {
public:
 const char* get_type_name();
 TypeKind get_type_kind(); // Returns POD, struct, array, function, member pointer, etc
 MemberType get_nested_type(size_t idx); // For struct, functions, members returns types for struct field, function arg, etc
 size_t get_size();
 size_t get_align();
 ...
};


В общем все эти классы представляют один узел в AST. Для доступа к атрибутам узла и потомкам узла в AST используются методы этих классов

Методы Member::put_data/Member::get_data/Member::call_method используются для 2го уровня - манипуляция с member'ами объекта по имени

Кстати, одной интроспекции недостаточно для стриминга произвольных классов. Стримить указатели, базируясь только на их типах увы не получится - проблемы распределения памяти под данные все равно придется решать вручную  smile 

PM MAIL   Вверх
boostcoder
Дата 26.7.2011, 21:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



xvr, спасибо. сначала попробую реализовать идею в терминах возможностей с++. а тогда уже и видно будет, что есть, а чего не хватает..
PM WWW   Вверх
boostcoder
Дата 26.7.2011, 23:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(xvr @  26.7.2011,  21:02 Найти цитируемый пост)
TypeKind get_type_kind();

тут TypeKind - enum?

Добавлено через 12 минут и 22 секунды
xvr, еще типа Object не хватает? или так задумано?
PM WWW   Вверх
borisbn
Дата 27.7.2011, 09:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Если wishlist ещё открыт, то могу предложить автогенерацию оператора == по указанным полям.
(как-то не очень понятно получается... щаз попробую на примере)
Код

struct S
{
    int id_1;
    int id_2;
    std::string description; // это так... для довеска
    std::string additional; // тоже
};
#pragma ( gen_operator_eq, S, id1, id2 )

эта pragma (не обязательно pragma... можно что угодно ) должна сгенерить след. код
Код

bool operator==( const S & left, const S & right ) {
    return left.id_1 == right.id_1 && left.id_2 == right.id_2;
}

если же эта прагма стоит внутри структуры/класса, то должен генериться оператор == с одним параметром


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
mes
Дата 27.7.2011, 10:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250





--------------------
PM MAIL WWW   Вверх
xvr
Дата 27.7.2011, 10:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(boostcoder @ 26.7.2011,  23:11)
Цитата(xvr @  26.7.2011,  21:02 Найти цитируемый пост)
TypeKind get_type_kind();

тут TypeKind - enum?

Да

Цитата

xvr, еще типа Object не хватает? или так задумано?
Можно обойтись и без Object. Просто в VCL Object был введен, что бы отличить VCL классы от нормальных С++ классов. Наследование от Object автоматически включало всю машинерию Delphi классов.
В других языках этот класс автоматически становится в предки любому классу. В С++ такого класса нет, и собственно интроспекция не требует его наличия.

PM MAIL   Вверх
borisbn
Дата 27.7.2011, 10:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



mes, спасибо. Вы последний комментарий читали (от юзера garex) ? smile
Да и не хочется таскать boost только ради этого... плюс к тому скорость этого метода (там же в комментариях замеряли) раза в полтора (!!!) ниже.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
boostcoder
Дата 27.7.2011, 11:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



borisbn, принято. это будет самая простая задача smile
PM WWW   Вверх
mes
Дата 27.7.2011, 11:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(borisbn @  27.7.2011,  09:35 Найти цитируемый пост)
Да и не хочется

ссылку дал, как информацию к размышлению, не более  smile 

Это сообщение отредактировал(а) mes - 27.7.2011, 11:30


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 27.7.2011, 13:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



xvr, поясните пожалуйста следующие моменты ;) а то в роде и понимаю, а вроде и нет..
Цитата(xvr @  26.7.2011,  21:02 Найти цитируемый пост)
size_t get_size();

Цитата(xvr @  26.7.2011,  21:02 Найти цитируемый пост)
size_t get_align();

Цитата(xvr @  26.7.2011,  21:02 Найти цитируемый пост)
size_t get_shift();



Up.
понял smile
get_size() - это sizeof(type)
get_align() - это выравнивание
get_shift() - смещение

Это сообщение отредактировал(а) boostcoder - 27.7.2011, 20:55
PM WWW   Вверх
boostcoder
Дата 27.7.2011, 14:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



эм.. вопрос: метаинформацию генерить для всех типов в единице трансляции?


и еще один: при компиляции нужно собирать метаинформацию о типах. где ее сохранять?
идея первая - в генерить статический_константный_массив. но проблема в том, что типов может быть тысячи ,что вызовет переполнение стека.
идея вторая - генерировать только инициализатор для массива. а при старте программы выделять память в куче и инициализировать ее. для этого в AST находим функцию main() и в нее иньектим init() который это проделает.

выскажитесь кто-нибудь ;)

Это сообщение отредактировал(а) boostcoder - 27.7.2011, 14:50
PM WWW   Вверх
Sahab
Дата 27.7.2011, 16:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 151
Регистрация: 1.9.2009

Репутация: нет
Всего: 3



Цитата(boostcoder @  27.7.2011,  14:38 Найти цитируемый пост)
метаинформацию генерить для всех типов в единице трансляции?

мне кажется только для "нужных" типов помеченных нами какой-нить прагмой
PM MAIL   Вверх
boostcoder
Дата 27.7.2011, 16:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(Sahab @  27.7.2011,  16:01 Найти цитируемый пост)
только для "нужных" типов помеченных нами какой-нить прагмой

а помечалка не устанет? smile руки-то не казенные...
в смысле, это как-то не логично, писать reflection и заставлять юзера помечать классы...

Это сообщение отредактировал(а) boostcoder - 27.7.2011, 17:14
PM WWW   Вверх
boostcoder
Дата 27.7.2011, 19:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



на данный момент разобрался со сбором инфы из AST.
1. итерироваться от глобального неймспейса по всем вложенным с неограниченным уровнем вложенности.
2. перечислять все декларации в любом из неймспейсов.
3. определить/фильтровать типы деклараций.
4. перечислять члены и вложенные декларации структур/классов с неограниченным уровнем вложенности.
5. добавлять/изменять AST.

вроде все что нужно...


пока что не нашел функцию, которая из строкового представления декларации генерит AST. потому как создавать AST "руками" это жесть smile 

Это сообщение отредактировал(а) boostcoder - 28.7.2011, 08:33
PM WWW   Вверх
boostcoder
Дата 27.7.2011, 19:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(xvr @  27.7.2011,  10:15 Найти цитируемый пост)
Цитата(boostcoder @ 26.7.2011,  23:11)
Цитата(xvr @  26.7.2011,  21:02 )
TypeKind get_type_kind();

тут TypeKind - enum?

Да

какие типы он должен перечислять? все POD`ы и один non_pod ?
PM WWW   Вверх
xvr
Дата 27.7.2011, 21:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(boostcoder @  27.7.2011,  14:38 Найти цитируемый пост)
эм.. вопрос: метаинформацию генерить для всех типов в единице трансляции?

Это должно настраиваться (через опции командной строки). Либо все, либо специально помеченные (и унаследованные от них)

Цитата(boostcoder @  27.7.2011,  14:38 Найти цитируемый пост)
идея первая - в генерить статический_константный_массив. но проблема в том, что типов может быть тысячи ,что вызовет переполнение стека.

угу, стек не переполнится - статические массивы помещаются не в стеке. Посмотрите, как генерятся RTTI таблицы, и постройте там же

Цитата(boostcoder @  27.7.2011,  19:00 Найти цитируемый пост)
 потому как создавать AST "руками" это жесть

Простые массивы с константами тоже сложно сгенерить?

Цитата(boostcoder @  27.7.2011,  19:41 Найти цитируемый пост)
какие типы он должен перечислять? все POD`ы и один non_pod ?

Все PODы и по одной штуке на каждую разновидность неPODов - функция, структура, массив, класс, и т.д. и т.п.

PM MAIL   Вверх
mes
Дата 27.7.2011, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  27.7.2011,  18:41 Найти цитируемый пост)
 все POD`ы и один non_pod ? 

 smile это как ?!



--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 28.7.2011, 00:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(xvr @  27.7.2011,  21:04 Найти цитируемый пост)
Это должно настраиваться (через опции командной строки). Либо все, либо специально помеченные (и унаследованные от них)

кстати вариант. при том, это возможно.

Цитата(xvr @  27.7.2011,  21:04 Найти цитируемый пост)
угу, стек не переполнится - статические массивы помещаются не в стеке.

ы. а где? smile 

Цитата(xvr @  27.7.2011,  21:04 Найти цитируемый пост)
Посмотрите, как генерятся RTTI таблицы, и постройте там же

это где смотреть?

Цитата(xvr @  27.7.2011,  21:04 Найти цитируемый пост)
Простые массивы с константами тоже сложно сгенерить?

сложно - понятие относительное. я вообще-то предполагаю, что должна быть функция генерящая AST из ("int i = 0;"). но пока что я ее не нашел.

Цитата(xvr @  27.7.2011,  21:04 Найти цитируемый пост)
Все PODы

это понятно.

Цитата(xvr @  27.7.2011,  21:04 Найти цитируемый пост)
функция, структура, массив, класс

дело в том, что массив в gcc тоже под... попробую отыскать возможность получить больше информации о ноде...

Добавлено через 45 секунд
Цитата(mes @  27.7.2011,  21:48 Найти цитируемый пост)
это как ?!

в моем понимании, не_POD - это все что содержит функции-члены.
PM WWW   Вверх
mes
Дата 28.7.2011, 00:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  27.7.2011,  23:12 Найти цитируемый пост)
ы. а где? 

в области данных

Добавлено через 8 минут и 17 секунд
Цитата(boostcoder @  27.7.2011,  23:12 Найти цитируемый пост)
что массив в gcc тоже под..

 smile 
Цитата(boostcoder @  27.7.2011,  23:12 Найти цитируемый пост)
, не_POD - это все что содержит функции-члены. 

а почему этот не_POD один, а каких тогда POD`ов много ?

раз уже подошли вплотную к AST, мож и POD'ам уделить внимание, чтоб не вводить в заблуждение хотя бы самого себя.. 



--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 28.7.2011, 00:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  28.7.2011,  00:21 Найти цитируемый пост)
в области данных

это как? по правде сказать, всегда старался избегать использования статических переменных..

Цитата(mes @  28.7.2011,  00:21 Найти цитируемый пост)
что массив в gcc тоже под..

прошу прощения, запутался...

по поводу POD`ов создам лучше отдельную тему. чтоб эту не хламить..

Цитата(mes @  28.7.2011,  00:21 Найти цитируемый пост)
а почему этот не_POD один, а каких тогда POD`ов много ?

раз уже подошли вплотную к AST, мож и POD'ам уделить внимание, чтоб не вводить в заблуждение хотя бы самого себя..

да-да-да. создаю тему.

PM WWW   Вверх
boostcoder
Дата 28.7.2011, 01:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(xvr @  27.7.2011,  21:04 Найти цитируемый пост)
(и унаследованные от них)

кстати, разобрался как итерироваться по узлам-предкам smile

Это сообщение отредактировал(а) boostcoder - 28.7.2011, 01:31
PM WWW   Вверх
kosmonaFFFt
Дата 28.7.2011, 05:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 538
Регистрация: 14.4.2008
Где: Иннополис

Репутация: нет
Всего: 5



Цитата(boostcoder @ 26.7.2011,  18:13)
т.е. получается, что все объекты типа Class ссылаются на какую-то глобальную карту. и данные для этой карты нужно генерировать в компайлтайм. а инициализировать в рантайм? правильно мыслю?

Добавлено @ 14:15
kosmonaFFFt, можешь показать тоже самое в коде? или в псевдокоде.

Псевдокод:

Код

Map<String, Class>  global_classes = new Map<String, Class>();
foreach (класс in все_классы_программы) {
    Class clazz = new Class(класс);
    global_classes.put(класс.getName(), clazz);
}


Тут я вижу 2 варианта - либо вставить код инициализации объектов Class в начало main(), либо сразу сгенерировать во время компиляции и поместить в секцию данных программы, или куда там статические данные идут... Главное, чтобы global_classes из примера выше был доступен в рантайме... Можно для начала просто попробовать C++ код сгенерировать, примерно как в Qt с их QMetaObject...
И да, если я что-то где-то не очень понятно объясняю, то это потому, что для меня основными языками являются Java и C#, и к наличию  reflection я привыкший...


--------------------
user posted image
PM MAIL ICQ   Вверх
boostcoder
Дата 28.7.2011, 08:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



6. итерироваться по списку аргументов со всеми вытекающими.
7. определить что поддерево является декларацией шаблона.
8. определить что поддерево является статической_переменной/статической_функцией/статическим_членом.

Добавлено @ 08:09
kosmonaFFFt, понял.
все же лучше использовать глобальный_статический_константный_объект.

Это сообщение отредактировал(а) boostcoder - 28.7.2011, 08:33
PM WWW   Вверх
kosmonaFFFt
Дата 28.7.2011, 08:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 538
Регистрация: 14.4.2008
Где: Иннополис

Репутация: нет
Всего: 5



Цитата(boostcoder @  28.7.2011,  12:08 Найти цитируемый пост)
все же лучше использовать глобальный_статический_константный_объект.


Ну да, тоже вариант...


--------------------
user posted image
PM MAIL ICQ   Вверх
xvr
Дата 28.7.2011, 09:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(boostcoder @  28.7.2011,  08:08 Найти цитируемый пост)
все же лучше использовать глобальный_статический_константный_объект.

Угу, только не объект (в понимании С++), а просто таблицы. Т.е. глобальный массив констант. Код, генерируемый gcc для RTTIEx не должен содержать исполняемого кода (т.е. неиспользуемая RTTIEx не должна вызывать накладных расходов run-time)

Яркий пример - уже упомянутые мною таблицы RTTI (смотреть в генерируемом ассемблере и в сорцах gcc), и таблицы для поддержки эксепшенов

PM MAIL   Вверх
boostcoder
Дата 28.7.2011, 09:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(xvr @  28.7.2011,  09:16 Найти цитируемый пост)
смотреть в генерируемом ассемблере и в сорцах gcc

Вы меня переоцениваете smile

Добавлено через 2 минуты и 33 секунды
Цитата(xvr @  28.7.2011,  09:16 Найти цитируемый пост)
Угу, только не объект (в понимании С++), а просто таблицы. Т.е. глобальный массив констант. Код, генерируемый gcc для RTTIEx не должен содержать исполняемого кода (т.е. неиспользуемая RTTIEx не должна вызывать накладных расходов run-time)

понятно.
PM WWW   Вверх
kosmonaFFFt
Дата 28.7.2011, 09:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 538
Регистрация: 14.4.2008
Где: Иннополис

Репутация: нет
Всего: 5



Цитата(xvr @  28.7.2011,  13:16 Найти цитируемый пост)
Т.е. глобальный массив констант. Код, генерируемый gcc для RTTIEx не должен содержать исполняемого кода (т.е. неиспользуемая RTTIEx не должна вызывать накладных расходов run-time)


ИМХО не обязательно, можно сделать что-то типа class-loader'а, который бы в рантайме по мере использования классов создавал бы нужную информацию... Хотя это уже будет не С++... smile


--------------------
user posted image
PM MAIL ICQ   Вверх
boostcoder
Дата 28.7.2011, 09:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(kosmonaFFFt @  28.7.2011,  09:57 Найти цитируемый пост)
который бы в рантайме

не нужно рантайм нагружать тем, что можно сделать и без него.
PM WWW   Вверх
boostcoder
Дата 28.7.2011, 17:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(boostcoder @  27.7.2011,  13:45 Найти цитируемый пост)
get_shift() - смещение

может тогда назвать его offset() ?
PM WWW   Вверх
boostcoder
Дата 28.7.2011, 18:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(xvr @  26.7.2011,  21:02 Найти цитируемый пост)
void call_method(void* ret_val, std::vector<AnyValue>& args);

а почему не ложить в вектор указатели на void?
PM WWW   Вверх
mes
Дата 28.7.2011, 21:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  28.7.2011,  17:24 Найти цитируемый пост)
а почему не ложить в вектор указатели на void? 

потярел нить, откуда появился этот код, но полагаю, потому что void * в отличии any не копиэйбл, а также не известно как его удалять.. 




--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 28.7.2011, 21:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



еще несколько вопросов.

как я понимаю, RTTIEX должен быть таким:
Код

struct rtti_ex_ {
   const char* name;
   type_ type;
   size_t size;
   size_t align;
};


где type - enum. так?
тогда вопрос: enum нужно генерить для всех типов в единице трансляции?

Добавлено через 1 минуту и 56 секунд
Цитата(mes @  28.7.2011,  21:37 Найти цитируемый пост)
потому что void * в отличии any не копиэйбл, а также не известно как его удалять..

не понял...
кот от xvr`а:
Код

class Class {
public:
 class member_iterator; // *member_iterator => Member
 member_iterator members_begin();
 member_iterator members_end();
 .... все остальные методы, типа find и пр .........
 Class(const char*); // create from string ID
 Class(void*); // create from Object
};
class Member {
public:
 MemberType get_type();
 const char* get_name();
 size_t get_shift();
 void put_data(void*);
 void get_data(void*);
 void call_method(void* ret_val, std::vector<AnyValue>& args);
};
class MemberType {
public:
 const char* get_type_name();
 TypeKind get_type_kind(); // Returns POD, struct, array, function, member pointer, etc
 MemberType get_nested_type(size_t idx); // For struct, functions, members returns types for struct field, function arg, etc
 size_t get_size();
 size_t get_align();
 ...
};


PM WWW   Вверх
xvr
Дата 28.7.2011, 22:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(boostcoder @  28.7.2011,  17:37 Найти цитируемый пост)
может тогда назвать его offset() ? 

Можно. А еще можно посмотреть интерфейсы в java.lang.reflection и скопировать идеи оттуда (насколько это будет возможно)
Цитата(boostcoder @  28.7.2011,  18:24 Найти цитируемый пост)
а почему не ложить в вектор указатели на void? 

В принципе можно. Но тогда на вызывающей стороне придется создавать все параметры в виде явных переменных и брать на них указатели. Кроме того, передавая значения в некой обвертке (AnyValue) можно существенно упростить жизнь вызывающей стороне, если дать возможность объекту Class проводить неявные преобразования аргументов. Например - если функция принимает параметр целочисленного типа, то вызывающая сторона может задать нечто типа long long и не вдаваться в подробности о конкретных размерах аргумента.

Цитата(boostcoder @  28.7.2011,  21:40 Найти цитируемый пост)
как я понимаю, RTTIEX должен быть таким:

Типа такого. Для составных типов (структур, классов, массивов, функций и т.п.) тут еще должны присутствовать такие же записи для всех вложенных элементах (поля структур, аргументы функций и пр)

Цитата(boostcoder @  28.7.2011,  21:40 Найти цитируемый пост)
тогда вопрос: enum нужно генерить для всех типов в единице трансляции?

Не enum'ы а инстансы rtti_ex_. Да, для всех.

PM MAIL   Вверх
boostcoder
Дата 28.7.2011, 22:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(xvr @  28.7.2011,  22:15 Найти цитируемый пост)
А еще можно посмотреть интерфейсы в java.lang.reflection

я ж не знал smile

Цитата(xvr @  28.7.2011,  22:15 Найти цитируемый пост)
В принципе можно. Но тогда на вызывающей стороне придется создавать все параметры в виде явных переменных и брать на них указатели. Кроме того, передавая значения в некой обвертке (AnyValue) можно существенно упростить жизнь вызывающей стороне, если дать возможность объекту Class проводить неявные преобразования аргументов. Например - если функция принимает параметр целочисленного типа, то вызывающая сторона может задать нечто типа long long и не вдаваться в подробности о конкретных размерах аргумента.

понял.

Цитата(xvr @  28.7.2011,  22:15 Найти цитируемый пост)
Типа такого. Для составных типов (структур, классов, массивов, функций и т.п.) тут еще должны присутствовать такие же записи для всех вложенных элементах (поля структур, аргументы функций и пр)

ага.

Цитата(xvr @  28.7.2011,  22:15 Найти цитируемый пост)
Не enum'ы а инстансы rtti_ex_. Да, для всех.

не понял...
PM WWW   Вверх
boostcoder
Дата 29.7.2011, 02:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



xvr, меня тут мысль посетила...
вот AST генерится на основании кода единицы трансляции. значит в нем(в AST) все связанно. а если я в этот AST добавлю свой подAST, то, прежний AST по идее станет незаконченным/неправильным/испорченным. так?
PM WWW   Вверх
kosmonaFFFt
Дата 29.7.2011, 05:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 538
Регистрация: 14.4.2008
Где: Иннополис

Репутация: нет
Всего: 5



Цитата(boostcoder @ 29.7.2011,  06:07)
xvr, меня тут мысль посетила...
вот AST генерится на основании кода единицы трансляции. значит в нем(в AST) все связанно. а если я в этот AST добавлю свой подAST, то, прежний AST по идее станет незаконченным/неправильным/испорченным. так?

Ну это думаю смотря как добавлять... AST это просто дерево, построенное из исходников, на основе которого генерируется промежуточный или машинный код, так что по сути эффект добавления чего-то в AST может быть эквивалентен эффекту добавления чего-то в исходники перед компиляцией...


--------------------
user posted image
PM MAIL ICQ   Вверх
boostcoder
Дата 29.7.2011, 07:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(kosmonaFFFt @  29.7.2011,  05:59 Найти цитируемый пост)
добавления чего-то в AST может быть эквивалентен эффекту добавления чего-то в исходники перед компиляцией

а вот я не уверен... нужно попробовать что-то сгенерить...
PM WWW   Вверх
kosmonaFFFt
Дата 29.7.2011, 07:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 538
Регистрация: 14.4.2008
Где: Иннополис

Репутация: нет
Всего: 5



Главное изменить AST до прохода всяческих оптимизаций, тогда вероятность ошибок уменьшится...
А вообще на тему компиляции могу посоветовать почитать что-то типа этого: http://www.proklondike.com/books/thobshee/compiler2.html


--------------------
user posted image
PM MAIL ICQ   Вверх
boostcoder
Дата 30.7.2011, 09:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(kosmonaFFFt @  29.7.2011,  07:46 Найти цитируемый пост)
Главное изменить AST до прохода всяческих оптимизаций

я его и изменяю сразу после построения.

еще вопрос.
допустим юзер хочет создать объект в неймспейсе:
Код

std::string* str = Class::create("std::string");

как быть?
получается что таблицу типов нужно генерить не в виде простого массива.. это должен быть массив cons`ов ? я правильно мыслю?
PM WWW   Вверх
xvr
Дата 30.7.2011, 09:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(boostcoder @  28.7.2011,  22:44 Найти цитируемый пост)
не понял... 

По одной штуке rtti_ex_ на каждый тип

Цитата(boostcoder @  30.7.2011,  09:37 Найти цитируемый пост)
как быть?

Я уже где то писал вверху - таблиц должно быть 2 штуки (точнее 2 набора таблиц) - 1 набор с RTTIEx (rtti_ex_) на каждый тип (извлекаются по уникальному имени, приблизительно таким же, как таблица для обычного RTTI). А вторая таблица - общая для всей программы. В нее складываются имена типов классов и адреса в 1ю таблицу RTTIEx.

Вторая таблица должна генерироваться в отдельной секции объектного файла, что бы линкер смог собрать ее из отдельных единиц трансляции (как он собирает вызовы конструкторов и деструкторов статических экземпляров объектов и таблицу для обработки исключений)

Вот пример:
Код

class A {
public:
 virtual int func();
};

int A::func() {return int(this);}

int main()
{
 A* a=new A;
 return a->func();
}

Вот результат 
Код

    .file    "rtti.cpp"
    .text
    .align 2
.globl __ZN1A4funcEv
    .def    __ZN1A4funcEv;    .scl    2;    .type    32;    .endef
__ZN1A4funcEv:
LFB2:
    pushl    %ebp
LCFI0:
    movl    %esp, %ebp
LCFI1:
    movl    8(%ebp), %eax
    popl    %ebp
    ret
LFE2:
    .section    .text$_ZN1AC1Ev,"x"
    .linkonce discard
    .align 2
.globl __ZN1AC1Ev
    .def    __ZN1AC1Ev;    .scl    2;    .type    32;    .endef
__ZN1AC1Ev:
LFB6:
    pushl    %ebp
LCFI2:
    movl    %esp, %ebp
LCFI3:
    movl    8(%ebp), %eax
    movl    $__ZTV1A+8, (%eax)
    popl    %ebp
    ret
LFE6:
    .def    ___main;    .scl    2;    .type    32;    .endef
    .text
.globl _main
    .def    _main;    .scl    2;    .type    32;    .endef
_main:
LFB3:
    leal    4(%esp), %ecx
LCFI4:
    andl    $-16, %esp
    pushl    -4(%ecx)
LCFI5:
    pushl    %ebp
LCFI6:
    movl    %esp, %ebp
LCFI7:
    pushl    %ebx
LCFI8:
    pushl    %ecx
LCFI9:
    subl    $32, %esp
LCFI10:
    call    ___main
    movl    $4, (%esp)
    call    __Znwj
    movl    %eax, %ebx
    movl    %ebx, (%esp)
    call    __ZN1AC1Ev
    movl    %ebx, -12(%ebp)
    movl    -12(%ebp), %eax
    movl    (%eax), %eax
    movl    (%eax), %edx
    movl    -12(%ebp), %eax
    movl    %eax, (%esp)
    call    *%edx
    addl    $32, %esp
    popl    %ecx
    popl    %ebx
    popl    %ebp
    leal    -4(%ecx), %esp
    ret
LFE3:
.globl __ZTV1A
    .section    .rdata$_ZTV1A,"dr"
    .linkonce same_size
    .align 8
__ZTV1A:
    .long    0
    .long    __ZTI1A
    .long    __ZN1A4funcEv
.globl __ZTS1A
    .section    .rdata$_ZTS1A,"dr"
    .linkonce same_size
__ZTS1A:
    .ascii "1A\0"
.globl __ZTI1A
    .section    .rdata$_ZTI1A,"dr"
    .linkonce same_size
    .align 4
__ZTI1A:
    .long    __ZTVN10__cxxabiv117__class_type_infoE+8
    .long    __ZTS1A
    .section    .eh_frame,"w"
Lframe1:
    .long    LECIE1-LSCIE1
LSCIE1:
    .long    0x0
    .byte    0x1
    .def    ___gxx_personality_v0;    .scl    2;    .type    32;    .endef
    .ascii "zP\0"
    .uleb128 0x1
    .sleb128 -4
    .byte    0x8
    .uleb128 0x5
    .byte    0x0
    .long    ___gxx_personality_v0
    .byte    0xc
    .uleb128 0x4
    .uleb128 0x4
    .byte    0x88
    .uleb128 0x1
    .align 4
LECIE1:
LSFDE5:
    .long    LEFDE5-LASFDE5
LASFDE5:
    .long    LASFDE5-Lframe1
    .long    LFB3
    .long    LFE3-LFB3
    .uleb128 0x0
    .byte    0x4
    .long    LCFI4-LFB3
    .byte    0xc
    .uleb128 0x1
    .uleb128 0x0
    .byte    0x9
    .uleb128 0x4
    .uleb128 0x1
    .byte    0x4
    .long    LCFI5-LCFI4
    .byte    0xc
    .uleb128 0x4
    .uleb128 0x4
    .byte    0x4
    .long    LCFI6-LCFI5
    .byte    0xe
    .uleb128 0x8
    .byte    0x85
    .uleb128 0x2
    .byte    0x4
    .long    LCFI7-LCFI6
    .byte    0xd
    .uleb128 0x5
    .byte    0x4
    .long    LCFI9-LCFI7
    .byte    0x84
    .uleb128 0x4
    .byte    0x83
    .uleb128 0x3
    .align 4
LEFDE5:
    .def    __Znwj;    .scl    2;    .type    32;    .endef

А вот он же, но с демангленными именами:
Код

    .file    "rtti.cpp"
    .text
    .align 2
.globl A::func()
    .def    A::func();    .scl    2;    .type    32;    .endef
A::func():
LFB2:
    pushl    %ebp
LCFI0:
    movl    %esp, %ebp
LCFI1:
    movl    8(%ebp), %eax
    popl    %ebp
    ret
LFE2:
    .section    .text$_ZN1AC1Ev,"x"
    .linkonce discard
    .align 2
.globl A::A()
    .def    A::A();    .scl    2;    .type    32;    .endef
A::A():
LFB6:
    pushl    %ebp
LCFI2:
    movl    %esp, %ebp
LCFI3:
    movl    8(%ebp), %eax
    movl    vtable for A+8, (%eax)
    popl    %ebp
    ret
LFE6:
    .def    ___main;    .scl    2;    .type    32;    .endef
    .text
.globl _main
    .def    _main;    .scl    2;    .type    32;    .endef
_main:
LFB3:
    leal    4(%esp), %ecx
LCFI4:
    andl    $-16, %esp
    pushl    -4(%ecx)
LCFI5:
    pushl    %ebp
LCFI6:
    movl    %esp, %ebp
LCFI7:
    pushl    %ebx
LCFI8:
    pushl    %ecx
LCFI9:
    subl    $32, %esp
LCFI10:
    call    ___main
    movl    $4, (%esp)
    call    operator new(unsigned int)
    movl    %eax, %ebx
    movl    %ebx, (%esp)
    call    A::A()
    movl    %ebx, -12(%ebp)
    movl    -12(%ebp), %eax
    movl    (%eax), %eax
    movl    (%eax), %edx
    movl    -12(%ebp), %eax
    movl    %eax, (%esp)
    call    *%edx
    addl    $32, %esp
    popl    %ecx
    popl    %ebx
    popl    %ebp
    leal    -4(%ecx), %esp
    ret
LFE3:
.globl vtable for A
    .section    .rdata$_ZTV1A,"dr"
    .linkonce same_size
    .align 8
vtable for A:
    .long    0
    .long    typeinfo for A
    .long    A::func()
.globl typeinfo name for A
    .section    .rdata$_ZTS1A,"dr"
    .linkonce same_size
typeinfo name for A:
    .ascii "1A\0"
.globl typeinfo for A
    .section    .rdata$_ZTI1A,"dr"
    .linkonce same_size
    .align 4
typeinfo for A:
    .long    vtable for __cxxabiv1::__class_type_info+8
    .long    typeinfo name for A
    .section    .eh_frame,"w"
Lframe1:
    .long    LECIE1-LSCIE1
LSCIE1:
    .long    0x0
    .byte    0x1
    .def    ___gxx_personality_v0;    .scl    2;    .type    32;    .endef
    .ascii "zP\0"
    .uleb128 0x1
    .sleb128 -4
    .byte    0x8
    .uleb128 0x5
    .byte    0x0
    .long    ___gxx_personality_v0
    .byte    0xc
    .uleb128 0x4
    .uleb128 0x4
    .byte    0x88
    .uleb128 0x1
    .align 4
LECIE1:
LSFDE5:
    .long    LEFDE5-LASFDE5
LASFDE5:
    .long    LASFDE5-Lframe1
    .long    LFB3
    .long    LFE3-LFB3
    .uleb128 0x0
    .byte    0x4
    .long    LCFI4-LFB3
    .byte    0xc
    .uleb128 0x1
    .uleb128 0x0
    .byte    0x9
    .uleb128 0x4
    .uleb128 0x1
    .byte    0x4
    .long    LCFI5-LCFI4
    .byte    0xc
    .uleb128 0x4
    .uleb128 0x4
    .byte    0x4
    .long    LCFI6-LCFI5
    .byte    0xe
    .uleb128 0x8
    .byte    0x85
    .uleb128 0x2
    .byte    0x4
    .long    LCFI7-LCFI6
    .byte    0xd
    .uleb128 0x5
    .byte    0x4
    .long    LCFI9-LCFI7
    .byte    0x84
    .uleb128 0x4
    .byte    0x83
    .uleb128 0x3
    .align 4
LEFDE5:
    .def    operator new(unsigned int);    .scl    2;    .type    32;    .endef

PM MAIL   Вверх
boostcoder
Дата 30.7.2011, 10:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(xvr @  30.7.2011,  09:59 Найти цитируемый пост)
Я уже где то писал вверху - таблиц должно быть 2 штуки (точнее 2 набора таблиц) - 1 набор с RTTIEx (rtti_ex_) на каждый тип (извлекаются по уникальному имени, приблизительно таким же, как таблица для обычного RTTI). А вторая таблица - общая для всей программы. В нее складываются имена типов классов и адреса в 1ю таблицу RTTIEx.

понял!

Цитата(xvr @  30.7.2011,  09:59 Найти цитируемый пост)
Вот пример

буду усваивать.
PM WWW   Вверх
xvr
Дата 30.7.2011, 10:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Строка 81 - таблица RTTI для класса A помещена в отдельную секцию (строка 82,86) с уникальным именем с пометкой для линкера (строка 83,88) оставить только 1 экземпляр этой секции. Причем отдельно размещены имя класса и собственно таблица typeinfo

В строке 93 в специальной секции помещается таблица для обработчика эксепшенов. Линкер соберет все такие секции со всей программы в 1 массив (секцию)

Кстати, мне тут пришла в голову мысль - стриминг данных, базирующийся на интроспекции конечно вещь весьма универсальная, но увы не очень эффективная. Т.к. в процессе работы программы будет по сути происходить интерпретация типов данных. Гораздо более эффективным был бы стримминг, для которого был бы сгенерирован готовый код на этапе трансляции. К сожалению это нельзя сделать универсальным способом, т.к. способ записи/чтения бинарного (или текстового) потока (а так же его структура) сильно зависят от приложения. Да и сам стриминг так же не может быть целиком описан только типами данных. Так что тут напрашивается некий генератор функций/классов для стриминга (видимо по некоторым, заданным пользователем шаблонам).

У меня пока нет ясного видения как это спроектировать  smile 


PM MAIL   Вверх
boostcoder
Дата 30.7.2011, 10:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



xvr, спасибо. разбираюсь smile 
PM WWW   Вверх
boostcoder
Дата 30.7.2011, 10:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(xvr @  30.7.2011,  10:11 Найти цитируемый пост)
стриминг данных

что имеется в виду?

PM WWW   Вверх
mes
Дата 30.7.2011, 10:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  30.7.2011,  09:33 Найти цитируемый пост)
Цитата

стриминг данных
что имеется в виду?

"отправление" данных в поток (stream) , или грубо говоря сериализация.. 




--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 30.7.2011, 10:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  30.7.2011,  10:49 Найти цитируемый пост)
грубо говоря сериализация

после того как разобрался с получением информации, интересна стала не только сериализация(reflection), но и нормальная introspection.
PM WWW   Вверх
mes
Дата 30.7.2011, 11:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  30.7.2011,  09:57 Найти цитируемый пост)
 не только сериализация(reflection), но и нормальная introspection

стало интересно, что для Вас reflection и introspection ? 


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 30.7.2011, 19:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



reflection/отражение:
Цитата

В информатике, отражение или рефлексия (синоним интроспекция, англ. reflection) означает процесс, во время которого программа может отслеживать и модифицировать собственную структуру и поведение во время выполнения. Парадигма программирования, положенная в основу отражения, называется рефлексивным программированием. Это один из видов метапрограммирования [1].
В большинстве современных компьютерных архитектур программные инструкции (код) хранятся как данные. Разница между кодом и данными в том, что выполняя код, компьютеры обрабатывают данные. То есть, 'инструкции' 'выполняются', а 'данные' 'обрабатываются' так, как предписано этими инструкциями. Однако, программы, написанные с помощью некоторых языков, способны обрабатывать собственные инструкции как данные и, таким образом, выполнять рефлексивные модификации. Такие самомодифицирующиеся программы в основном создаются с помощью высокоуровневых языков программирования, использующих виртуальные машины (например, Smalltalk, скриптовые языки). Также рефлексия используется в языках с объявляемыми и/или статическими типами (например, Java, Си, ML, Haskell).


introspection:
Цитата

Интроспекция (англ. type introspection) в программировании — возможность в некоторых объектно-ориентированных языках определить тип и структуру объекта во время выполнения программы. Эта возможность особенно заметна в языке Objective C, однако имеется во всех языках, позволяющих манипулировать типами объектов как объектами первого класса. Интроспекция может использоваться для реализации полиморфизма.

вроде как я все правильно понимаю..


да и не в этом суть. xvr меня озадачил ассемблерным кодом и всем сопутствующим...
конечно, если бы кто-то ткнул в ссылку или пример, все было бы сильно проще smile
PM WWW   Вверх
xvr
Дата 30.7.2011, 20:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(boostcoder @  30.7.2011,  19:36 Найти цитируемый пост)
конечно, если бы кто-то ткнул в ссылку или пример

Чего нет, того нет. Но есть соображение, что структуры данных (таблиц RTTIEx) должны быть по сути сериализованной версией AST (в части описания типов). 
PM MAIL   Вверх
boostcoder
Дата 3.8.2011, 23:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



на идею не забил. просто сейчас по теме больше общаюсь на stackoverflow и в списке рассылке gnu-gcc. вроде как есть надежда понять всю эту магию.
PM WWW   Вверх
boostcoder
Дата 20.8.2011, 11:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



в общем, ковыряниями/тыканиями/читаниями, ничего не получается. доки мало. почти нет.
пришел к решению, дважды обрабатывать единицу трансляции. первый раз - для сбора инфы, второй - для компиляции.
и того, процесс получится таким:
1. запускаем компилятор+плагин для сбора информации.
2. плагин из исходного файла и собранной информации генерит временный файл и завершает компилятор.
3. компилим временный файл как обычно.

вроде все логично...

Добавлено через 1 минуту и 28 секунд
xvr, скажите, а секция данных, может быть любого размера? есть хоть какие-то ограничения?
PM WWW   Вверх
xvr
Дата 20.8.2011, 11:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(boostcoder @  20.8.2011,  11:27 Найти цитируемый пост)
xvr, скажите, а секция данных, может быть любого размера?

Отдельно взятая секция не может превосходить размера адресного пространства (т.е. 4G на 32bit приложении). Форматы файлов (elf/PE) могут налагать дополнительные ограничения. Но скорее всего гораздо быстрее сломается компилятор/линкер/да и сама программа в run-time. Но в любом случае размеры любых секций до десятков мегабайт должны восприниматься без особых проблем

PM MAIL   Вверх
boostcoder
Дата 20.8.2011, 11:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(xvr @  20.8.2011,  11:35 Найти цитируемый пост)
размеры любых секций до десятков мегабайт должны восприниматься без особых проблем

вот и славно.
PM WWW   Вверх
boostcoder
Дата 1.10.2011, 17:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



давайте попытаемся сэмитировать необходимое поведение/реализацию, как будто для этого достаточно только языковых средств.
такой код:
Код

#include <iostream>

namespace reflect {

/***************************************************************************/

enum class type_ {
   char_, uchar_, short_, ushort_, int_, uint_, long_, ulong_,
   int64_, uint64_, array_, pointer_, double_, long_double_, float_,
   class_
};

struct rtti_ex_ {
   const char* name;
   const type_ type;
   const size_t size;
   const size_t align;
   const size_t offset;
};

/***************************************************************************/

struct member_type_ {
   const char* const name;
   const type_ type;
   const size_t size;
   const size_t align;
};

/***************************************************************************/

template<typename... Args>
struct args_pack {
   args_pack(const Args&...) {}
};

/***************************************************************************/

struct member_ {
   member_type_ type() const {}
   const char* name() const {}
   size_t offset() const {}
   
   template<typename... Args>
   void invoke(void* ptr, const args_pack<Args...>& args) {std::cout<<__PRETTY_FUNCTION__<<std::endl;}
   
   void set(const void* ptr) {std::cout<<__PRETTY_FUNCTION__<<std::endl;}
   void get(void* ptr) const {std::cout<<__PRETTY_FUNCTION__<<std::endl;}
};

typedef member_* member_iterator;
typedef const member_* member_const_iterator;

/***************************************************************************/

struct class_ {
   class_(const char* name) {}
   class_(const std::string& name) {}
   
   static void* create(const char* name) {}

   member_const_iterator begin() const {}
   member_const_iterator end() const {}
   member_iterator begin() {}
   member_iterator end() {}
   
   bool contains(const char* name) const {}
   
   member_const_iterator find(const char* name) const {}
   member_iterator find(const char* name) {}

   const member_& nested(size_t idx) const {}
   member_& nested(size_t idx) {}
};

typedef class_* class_iterator;

/***************************************************************************/

class_iterator find(const char* name) {}

/***************************************************************************/

} // namespace reflect

// типа пользовательский код. для симуляции.
// цифры - ID`ы
struct name1 {}; // 0
struct type1 {}; // 1

struct name3 { // 2
   name1 n; // [2, 0]
   type1 t; // [2, 1]
};

struct name2 { // 3
   struct name3 { // [3, 4]
      int a; // [3, 4, 5]
      type1 t; // [3, 4, 1]
   };
   name1 n; // [3, 0]
   type1 t; // [3, 1]
   name3 a;  // [3, 2]
};

// типа сгенеринная таблица.
static const reflect::rtti_ex_
_rtti[] = {
   // name,  type,                   sizeof, allign, offset (?)
   {"name1", reflect::type_::class_, 1,      4,      0},
   {"type1", reflect::type_::class_, 1,      4,      1},
   {"name3", reflect::type_::class_, 2,      4,      2},
   {"name2", reflect::type_::class_, 4,      4,      4}
};

/***************************************************************************/

int main() {
   // получение информации о типе "name1"
   // для этого, перебираем все элементы массива таблиц _rtti
   // тут, к примеру, для получения информации о типе "name2::name3", его имя необходимо указать полностью
   reflect::class_ c1("name1");
   
   // получение информации о типе "name1"
   reflect::class_ c2("name2");
   // поиск декларации типа "name3"
   reflect::member_const_iterator beg = c2.find("name3");
   reflect::member_const_iterator end = c2.end();
   // перечисляем члены "name2::name3"
   while ( ++beg < end ) {
   }
}


http://liveworkspace.org/code/8aae0e0cfb55...28c20b3ceadf96f

начиная с 86ой строки, я пытался сэмитировать поведение.
возникло два вопроса:
1. член offset, структуры rtti_ex_, каково должно быть его значение для типов самого верхнего уровня? т.е. тех, что не являются чьими-то членами.
2. по идее, rtti_ex_, должен содержать массив типов member_type_ ? или же, rtti_ex_ должны ссылаться на другие rtti_ex_, и тип member_type_ вообще лишний?

Добавлено @ 17:55
еще непонятно как быть при декларации данных-членов, и декларации типов-членов, как например "name2::name3"

Добавлено через 13 минут и 2 секунды
по идее, в "enum type_" нужно добавить член decl_, который будет указывать на то, что элемент rtti_ex_ описывает декларацию структуры(или что еще попадает под декларации? typedef?).

Это сообщение отредактировал(а) boostcoder - 1.10.2011, 17:56
PM WWW   Вверх
xvr
Дата 2.10.2011, 11:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(boostcoder @  1.10.2011,  17:50 Найти цитируемый пост)
возникло два вопроса:
1. член offset, структуры rtti_ex_, каково должно быть его значение для типов самого верхнего уровня? т.е. тех, что не являются чьими-то членами.

Ну например -1

Цитата(boostcoder @  1.10.2011,  17:50 Найти цитируемый пост)
2. по идее, rtti_ex_, должен содержать массив типов member_type_ ? или же, rtti_ex_ должны ссылаться на другие rtti_ex_, и тип member_type_ вообще лишний?

И rtti_ex_ и member_type_ внутренние структуры, которые собственно и должен генерить компилятор. Пользователь должен работать только с функциональным интерфейсом (class_ и member_), и не иметь доступа к внутренней реализации.

Что касается массивов member_type_ в rtti_ex_, то да, там должен быть указатель на массив member'ов (для структур/классов). И в принципе member_type_ действительно может отсутствовать, т.к. сейчас он полностью перекрывается с rtti_ex_.

В принципе member_type_ должен содержать поле offset, имя и ссылку на rtti_ex_. rtti_ex_ не должен содержать offset.

Цитата(boostcoder @  1.10.2011,  17:50 Найти цитируемый пост)
еще непонятно как быть при декларации данных-членов, и декларации типов-членов, как например "name2::name3"

Для них ввести специальные сущности в enum class type_

rtti_ex_ должен описывать тип, а member_type_ - инстанс (переменную верхнего уровня, или поле в структуре (типе))

PM MAIL   Вверх
boostcoder
Дата 2.10.2011, 18:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(xvr @  2.10.2011,  11:25 Найти цитируемый пост)
Ну например -1

ага.

Цитата(xvr @  2.10.2011,  11:25 Найти цитируемый пост)
Что касается массивов member_type_ в rtti_ex_, то да, там должен быть указатель на массив member'ов (для структур/классов). И в принципе member_type_ действительно может отсутствовать, т.к. сейчас он полностью перекрывается с rtti_ex_.

понял.

Цитата(xvr @  2.10.2011,  11:25 Найти цитируемый пост)
В принципе member_type_ должен содержать поле offset, имя и ссылку на rtti_ex_. rtti_ex_ не должен содержать offset.

действительно.

Цитата(xvr @  2.10.2011,  11:25 Найти цитируемый пост)
rtti_ex_ должен описывать тип, а member_type_ - инстанс (переменную верхнего уровня, или поле в структуре (типе))

ок.

PM WWW   Вверх
boostcoder
Дата 4.10.2011, 00:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



xvr, скажите, а как быть с повторами элементов глобального массива rtti_ex_? получится так, что для каждой единицы трансляции будет сгенерен такой массив. ведь элементы в таких массивах будут в большинстве своем повторяться. я понимаю(вроде как) что код использующий массив типов rtti_ex_ этой единицы трансляции будет знать только об этом массиве, и никакие перекрестные ссылки не будут иметь место. но все же, насколько это логично, и правильно ли я размышляю?
PM WWW   Вверх
xvr
Дата 4.10.2011, 09:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(boostcoder @  4.10.2011,  00:17 Найти цитируемый пост)
xvr, скажите, а как быть с повторами элементов глобального массива rtti_ex_?

Надо бороться  smile 
Цитата(boostcoder @  4.10.2011,  00:17 Найти цитируемый пост)
что код использующий массив типов rtti_ex_ этой единицы трансляции будет знать только об этом массиве, и никакие перекрестные ссылки не будут иметь место. 

Угу. Я уже приводил пример, как с этим борются в GCC - массив создается только на этапе линковки (линкером) из содержимого специальной секции. Каждый экземпляр rtti_ex_ помещается в отдельную именованную (именем замангленного типа) виртуальную секцию, и линкер на этапе линковки выкидывает дублирующиеся элементы, а все, что осталось, помещает в массив (точнее в отдельную секцию - в GCC доступ к экземплярам rtti производится по метке с именем, а не по индексу в массиве).

PM MAIL   Вверх
boostcoder
Дата 5.10.2011, 01:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(boostcoder @  20.8.2011,  11:27 Найти цитируемый пост)
в общем, ковыряниями/тыканиями/читаниями, ничего не получается. доки мало. почти нет.
пришел к решению, дважды обрабатывать единицу трансляции. первый раз - для сбора инфы, второй - для компиляции.

отменяется. разобрался с модификацией AST из плагина. есть возможность генерить что угодно. нарукоблудил несколько кодов декларации переменных/структур/функций/методов. никаких особых сложностей нет. все даже проще чем я ожидал smile

и, оказалось, что при модификации/добавлении чего-либо в AST, оно не "портиться"(о чем я переживал), и последующие алгоритмы обработки AST схватывают абсолютно все что в нем. ведь в плагин, AST передается сразу после разбора единицы трансляции. т.е. никакие алгоритмы/оптимизаторы еще не отработали.

Это сообщение отредактировал(а) boostcoder - 5.10.2011, 01:18
PM WWW   Вверх
boostcoder
Дата 6.10.2011, 08:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



итак. давайте начнем с простого.
создадим библиотечный код, который позволит программе использующей его, скомпилиться. даже если к единице трансляции не был применен плагин.
Код

namespace reflectpp {

void* create(const char* name, ...) { throw std::runtime_error("error!"); }
void* clone(void* ptr) { throw std::runtime_error("error!"); }

} // namespace reflectpp


использоваться это дело будет так:
Код

struct type {};

type* t1 = reflectpp::create("type");
type* t2 = reflectpp::clone(t1);

тут, для create(), мне нужно изменить строку на такую: "new type;"
если же конструктор типа требует аргументы - заменяем так: "new type(arg1, arg2, ...);"

clone. тут мне нужно определить тип на который указывает аргумент, и сформировать такую строку: "new type(*t1);"


пока все верно?

Это сообщение отредактировал(а) boostcoder - 6.10.2011, 08:56
PM WWW   Вверх
xvr
Дата 6.10.2011, 09:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(boostcoder @  6.10.2011,  08:28 Найти цитируемый пост)
тут, для create(), мне нужно изменить строку на такую: "new type;"

Угу

Цитата(boostcoder @  6.10.2011,  08:28 Найти цитируемый пост)
если же конструктор типа требует аргументы - заменяем так: "new type(arg1, arg2, ...);"

Так, но есть одно 'но' - как задать аргументы? reflectpp::create должен иметь фиксированную сигнатуру, т.е. аргументы придется передавать массивом чего то типа VARIANT. Передавать через ... не вариант - это потребует знать тип и количество аргументов статически в момент вызова reflectpp::create, что сводит на нет всю идею рефлексии  smile 

Цитата(boostcoder @  6.10.2011,  08:28 Найти цитируемый пост)
clone. тут мне нужно определить тип на который указывает аргумент, и сформировать такую строку: "new type(*t1);"

Угу


PM MAIL   Вверх
boostcoder
Дата 6.10.2011, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



xvr, я тут вот что подумал..
для создания объектов произвольного типа, в структуру rtti_ex_ нужно добавить метод(указатель на функцию?) create(). так ведь? ну и free(), за одно.

т.е. что-то типа этого:
Код


typedef void*(*create_fn)();
typedef void(*free_fn)();

struct rtti_ex_ {
   const char* name;
   const type_ type;
   const size_t size;
   const size_t align;
   create_fn create_;
   free_fn free_;
};

...

// сгенерированные функции создающая/удаляющая свой конкретный тип.
void* create_type() { return new type;}
void free_type(void* ptr) { delete static_cast<type*>(ptr); }

static const rtti_ex_ rtti_[] = {
   {"type", class_, 1, 4, &create_type, &free_type},
   { ... }
};


верно мыслю?
PM WWW   Вверх
boostcoder
Дата 6.10.2011, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(boostcoder @  6.10.2011,  12:23 Найти цитируемый пост)
ну и free(), за одно.

по поводу этого не уверен.
PM WWW   Вверх
boostcoder
Дата 6.10.2011, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



опишу заново свое видение всего этого добра, чтоб расставить точки где надо.

1. функция create().
возможные варианты использования:
Код

// при подобном использовании, просто создается объект указанного типа, но не помещается в карту объектов.
type1* t1 = reflectpp::create("type1");

// при подобном использовании, создается объект указанного типа и помещается в карту объектов name -> ptr
type1* t1 = reflectpp::create("object_name = type1");

карта типов нужна для:
Код

// 1. для получения уже созданного объекта
type1* t1 = reflectpp::get("object_name");

// 2. для создания клона объекта находящегося в карте. по имени объекта определяется его тип и создается новый объект инициализируемый объектом с именем object_name
// невозможно использовать clone() для объектов не находящихся в карте.
type1* t1 = reflectpp::clone("object_name");

т.е. нужна карта типа такой:
Код

std::unordered_map<size_t, void*>

где ключ - хеш сумма от имени, значение - указатель на объект.
и еще одна типа такой:
Код

std::unordered_map<void*, rtti_ex_*>

где ключ - указатель на объект, значение - указатель на rtti_ex_ этого типа.
по идее, нужна еще и третья карта, позволяющая создавать объекты типа class_ по имени типа.
еще один пример:
Код

struct type {
   void m1() {}
   int v1;
};

int main() {
   // не сохраняем в карту
   type* t1 = reflectpp::create("type");

   // сохраняем под именем "t2"
   type* t2 = reflectpp::create("t2 = type");
   std::cout << t2->v1 << std::endl;

   // вызов метода не возвращающего значения. первый аргумент(адрес возврата результата) == NULL
   reflectpp::invoke(0, "t2.m1");
   // присваивание значения переменной-члену v1
   reflectpp::invoke(0, "t2.v1", 33);
   // чтение переменной-члена v1
   int res = 0;
   reflectpp::invoke(&res, "t2.v1");

   // присваивание значения переменной-члену v1
   reflectpp::set("t2.v1", 33);
   // чтение переменной-члена v1
   int res = 0;
   reflectpp::get(&res, "t2.v1");

   // получение информации о типе по имени типа
   reflectpp::class_ ti("type");
   for ( reflect::member_const_iterator it = ti.begin(); it != ti.end(); ++it ) {
      std::cout
      << "name: " << it->name() << std::endl
      << "type: " << it->type() << std::endl
      << "size: " << it->size() << std::endl
      << "align: " << it->align() << std::endl
      << "offset: " << it->offset() << std::endl;

      if ( it->type() == reflectpp::type_::class_ ) {
         reflectpp::class_ ti(it->name());
         for ( reflect::member_const_iterator it = ti.begin(); it != ti.end(); ++it ) {
            std::cout
            << "name: " << it->name() << std::endl
            << "type: " << it->type() << std::endl
            << "size: " << it->size() << std::endl
            << "align: " << it->align() << std::endl
            << "offset: " << it->offset() << std::endl;
      }
   }

   // получение информации о типе по указателю на объект
   reflectpp::class_ ti(t1);
   for ( reflect::member_const_iterator it = ti.begin(); it != ti.end(); ++it ) {
      std::cout
      << "name: " << it->name() << std::endl
      ...

   // получение информации о типе по имени объекта находящегося в карте
   reflectpp::class_ ti("t1");
   for ( reflect::member_const_iterator it = ti.begin(); it != ti.end(); ++it ) {
      std::cout
      << "name: " << it->name() << std::endl
      ...
}


мне не нравится присутствие трех карт.
какие предложения по этому поводу?

Это сообщение отредактировал(а) boostcoder - 6.10.2011, 16:11
PM WWW   Вверх
mes
Дата 6.10.2011, 16:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  6.10.2011,  14:27 Найти цитируемый пост)
по идее, нужна еще и третья карта, позволяющая создавать объекты типа class_ по имени типа.

во первых почему создавать, во вторых зачем Вам столько карт ?   smile

во вторых Вы собрали в одну лукошко разные по сути и природе явления.. 


Это сообщение отредактировал(а) mes - 6.10.2011, 16:17


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 6.10.2011, 16:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



mes, Ваши предложения?
PM WWW   Вверх
mes
Дата 6.10.2011, 16:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



и так есть у вас  _тип_ зная его Вы можете  как создать объект, так и удалить его.. 
_тип_ у Вас создается при запуске программы и держится до конца..  Вам нужно не создавать, а получать.. 
хранить ли ассоциацию картой или сделать просто список _типов_, или список таблиц _типов_ зависит от вашей концепции..

Цитата(boostcoder @  6.10.2011,  15:22 Найти цитируемый пост)
mes, Ваши предложения? 

трудно сказать, потому что концепция к которой Вы стремитесь не до конца ясна..

прежде всего rtti_ex предназначена для любых типов или только для классовых ?
если для всех, то вопрос, для чего может понадобиться создание объекта неполиморфного класса по имени ?!


Это сообщение отредактировал(а) mes - 6.10.2011, 16:26


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 6.10.2011, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  6.10.2011,  16:22 Найти цитируемый пост)
прежде всего rtti_ex предназначена для любых типов или только для классовых ?

для всех.

Цитата(mes @  6.10.2011,  16:22 Найти цитируемый пост)
если для всех, то вопрос, для чего может понадобиться создание объекта неполиморфного класса по имени ?!

по простому - юзер будет в терминале вводить имя.

или же так:
Код

reflectpp::script("
t1 = type1;
print t1;

if t1 == type_::class_
   for it in t1.members
      print it;
");

или так:
Код

std::ifstream file("filename");
std::string str((std::istream_iterator<char>(file)), (std::istream_iterator<char>()));

reflectpp::script(str);


Это сообщение отредактировал(а) boostcoder - 6.10.2011, 16:42
PM WWW   Вверх
mes
Дата 6.10.2011, 16:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  6.10.2011,  15:33 Найти цитируемый пост)
по простому - юзер будет в терминале вводить имя.

ну создал юзер тип int  как void *  и что делать с ним дальше ?
если Вы о том что в яве и шарпе можно создавать интегральные типы, так только те что являются по сути объектами.. т.е. только полиморфные типы.. 
можно конечно преврать и простые типы в полиморфные посредством например интектуального указателя.. но опять напрашивается вопрос, что за модель у нас в конце тунеля ? или просто попытка набросать побольше фичей, без учета возможностей их иоспользования ?

Добавлено через 2 минуты и 39 секунд
Цитата(boostcoder @  6.10.2011,  15:33 Найти цитируемый пост)
reflectpp::script(str);

smile хотите загнать всю стат-информацию о типах в рантайм ?  smile 


--------------------
PM MAIL WWW   Вверх
Sahab
Дата 6.10.2011, 20:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 151
Регистрация: 1.9.2009

Репутация: нет
Всего: 3



Цитата(mes @  6.10.2011,  16:49 Найти цитируемый пост)
просто попытка набросать побольше фичей, без учета возможностей их иоспользования ?

а зачем ограничивать юзера, мало ли что ему может понадобиться?
PM MAIL   Вверх
mes
Дата 6.10.2011, 21:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(Sahab @  6.10.2011,  19:19 Найти цитируемый пост)
а зачем ограничивать юзера, мало ли что ему может понадобиться? 

я тоже противник ограничений, но давать юзеру пол-лопатки и дырявое ведерко, для меня не что иное как издевательство   smile 

Это сообщение отредактировал(а) mes - 6.10.2011, 21:26


--------------------
PM MAIL WWW   Вверх
kosmonaFFFt
Дата 7.10.2011, 06:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 538
Регистрация: 14.4.2008
Где: Иннополис

Репутация: нет
Всего: 5



Цитата(boostcoder @  6.10.2011,  19:27 Найти цитируемый пост)
1. функция create().возможные варианты использования:код C++1:2:3:4:5:// при подобном использовании, просто создается объект указанного типа, но не помещается в карту объектов.type1* t1 = reflectpp::create("type1");// при подобном использовании, создается объект указанного типа и помещается в карту объектов name -> ptrtype1* t1 = reflectpp::create("object_name = type1");


Может не reflectcpp::create("obj_name = type1"), а reflectcpp::create("type1", "obj_name")?

И еще мое мнение - раз уж это для C++, не лучше ли будет использовать вместо char* нормальный std::string и классы вместо структур с функциями?


--------------------
user posted image
PM MAIL ICQ   Вверх
mes
Дата 7.10.2011, 09:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(kosmonaFFFt @  7.10.2011,  05:40 Найти цитируемый пост)
 и классы вместо структур с функциями? 

структура с функциями это тот же класс..  иногда удобнее, потому что по умолчанию public.. 



--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 7.10.2011, 10:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



mes, что конкретно Вы хотите сказать? без намеков, пожалуйста.

Цитата(kosmonaFFFt @  7.10.2011,  06:40 Найти цитируемый пост)
Может не reflectcpp::create("obj_name = type1"), а reflectcpp::create("type1", "obj_name")?

тут есть некоторая неопределенность.
Код

// без аргументов, но не сохранять в карту объектов
reflectpp::create("type1");
// с аргументами, но не сохранять в карту объектов.
reflectpp::create("type1", arg0, ...); // <<<<<<<<<<<<<<<<<<<<< 1

// без аргументов, но сохранить в карту объектов. вариант 1.
reflectpp::create("obj_name = type1");
// без аргументов, но сохранить в карту объектов. вариант 2.
reflectpp::create("type1", "obj_name"); // <<<<<<<<<<<<<<<<<<<<< 2


отметки 1 и 2. т.е. вторым аргументом может быть как имя объекта, так и аргумент в конструктор объекта.
хотя я склоняюсь к тому, чтоб обязать юзера паковать аргументы в класс-обертку, например такой: http://liveworkspace.org/code/7f3184c1c270...a6f850de238eccb
Код

#include <iostream>
#include <cassert>

struct args_pack {
   args_pack()
      :_count(0),
      _args{0}
   {}

   template<typename... Types>
   args_pack(const Types&... types)
      :_count(sizeof...(types)),
      _args{&types...}
   {
      static_assert(sizeof...(types) <= _max_args, "error! arguments more then 10.");
   }

   size_t count() const { return _count; }
   const void** args() const { return (const void**)_args; }

private:
   static const size_t _max_args = 10;
   size_t _count;
   const void* _args[_max_args];
};

int main() {
   int i;
   long l;
   const char* cc = "cc";

   args_pack a1(i);
   args_pack a2(i, l);
   args_pack a3(i, l, cc);

   const void** p1 = a1.args();
   assert(a1.count() == 1 && p1[0] == &i);

   const void** p2 = a2.args();
   assert(a2.count() == 2 && p2[0] == &i && p2[1] == &l);

   const void** p3 = a3.args();
   assert(a3.count() == 3 && p3[0] == &i && p3[1] == &l && p3[2] == &cc);
}


Добавлено через 6 минут и 19 секунд
т.е. использоваться это будет как-то так:
Код

reflectpp::invoke("t1.m1", args_pack(i, j));


Это сообщение отредактировал(а) boostcoder - 7.10.2011, 10:13
PM WWW   Вверх
mes
Дата 7.10.2011, 11:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  7.10.2011,  09:09 Найти цитируемый пост)
 что конкретно Вы хотите сказать? без намеков, пожалуйста.


ну вот возьмем Ваш последний пример.. 
Цитата(boostcoder @  7.10.2011,  09:09 Найти цитируемый пост)
  const void* _args[_max_args];

зачем тогда нужна вся rtti_ex, если в конечном счете никакой безопасности при передачи аргументов ?
если хотите динамическую типизацию, так делайте ее, если достаточно небезопасного инвокинга - делайте его, 
но не надо смешивать различные подходы в один соус.. smile пол-лопатки вряд ли кому нужны.. 



Это сообщение отредактировал(а) mes - 7.10.2011, 11:12


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 7.10.2011, 12:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  7.10.2011,  11:11 Найти цитируемый пост)
зачем тогда нужна вся rtti_ex, если в конечном счете никакой безопасности при передачи аргументов ?

что конкретно я не правильно делаю? объясните.
PM WWW   Вверх
boostcoder
Дата 7.10.2011, 13:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  7.10.2011,  11:11 Найти цитируемый пост)
пол-лопатки

половина лопаты? а в чем смысл фразы?
PM WWW   Вверх
mes
Дата 7.10.2011, 13:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  7.10.2011,  11:03 Найти цитируемый пост)
что конкретно я не правильно делаю? объясните. 

не связываете объекты с рантайм информацией..

Добавлено через 2 минуты
Цитата(boostcoder @  7.10.2011,  12:35 Найти цитируемый пост)
половина лопаты? а в чем смысл фразы? 

так объсните что я могу делать с void* , если тип задан в рантайме..

Добавлено через 4 минуты и 48 секунд
Вы оглядываетесь на языки (ява, шарп и т.д.) и думаете почему в них есть рефлексия и все плюшки для простых типов, а Вам на С++ нельзя... так ?
так в тех языках, эти простые типы далеко не так просты, и каждый является объектом.. т.е. (как минимум) имеет ссылку на тип, к которому он принадлежит..
а так же существует целый ряд правил, о совместимости этих типов..

Добавлено через 8 минут и 15 секунд
кстати c++/cli (для .net) тоже умеет многое из названного, но зато какими жертвами.. 
smile


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 7.10.2011, 13:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  7.10.2011,  13:37 Найти цитируемый пост)
не связываете объекты с рантайм информацией..

+
Цитата(mes @  7.10.2011,  13:37 Найти цитируемый пост)
так объсните что я могу делать с void* , если тип задан в рантайме..

= Ваши предложения?
PM WWW   Вверх
kosmonaFFFt
Дата 7.10.2011, 13:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 538
Регистрация: 14.4.2008
Где: Иннополис

Репутация: нет
Всего: 5



Цитата(boostcoder @  7.10.2011,  14:09 Найти цитируемый пост)
Цитата(kosmonaFFFt @  7.10.2011,  06:40 )Может не reflectcpp::create("obj_name = type1"), а reflectcpp::create("type1", "obj_name")?тут есть некоторая неопределенность.


Я тут подумал, и, по моему, регистрация уже созданных объектов в ком-нибудь словаре по имени немного из другой области - обычно такая функциональность встречается в IOC контейнерах и к reflection отношения имеет мало, например в Java и C# в reflection такого нет...

Передача параметров в виде "obj_name = type1" тоже на мой взгляд неудачна, т. к. во первых придется писать парсер выражений, а во вторых нарушается статичекая типизация C++... Если и делать регистрацию объектов в контейнере, то лучше отдельным методом...

Цитата(mes @  7.10.2011,  13:06 Найти цитируемый пост)
Цитата(kosmonaFFFt @  7.10.2011,  05:40 ) и классы вместо структур с функциями? структура с функциями это тот же класс..  иногда удобнее, потому что по умолчанию public.


Я имел в виду, что не лучше ли сделать вместо структуры rtti_ex и функций по работе с ней класс, например RttiEx, получать объект этого класса для типа и работать дальше с ними... Примерно так:
Код


class MySuperClass {
...
};

int main(...) {
   
    RttiEx myClass = RttiEx::get("MySuperClass"); // или например RttiEx myClass("MySuperClass");
    void* obj = myClass.create(/* тут могут быть аргументы конструктора */);
    
    Field f = myClass.getFields()[0];
    f.setValue(obj, "SuperFieldValue"); // Например так можно задавать значение поля через reflection.

    // А например так можно сделать вызов методов...
    for (RttiEx::MethodIterator mit = myClass.getMethods().begin; mit != myClass.getMethods().end(); ++mit) {
        void* result = mit->invoke(obj /*, тут могут быть параметры метода, а могут и не быть... */);
    }
}


Соответственно классы RttiEx, Field, Method из вышеприведенного примера будут реализованы в reflection-библиотеке и предоставлять универсальный механизм для работы с объектами и классами в рантайме...


Это сообщение отредактировал(а) kosmonaFFFt - 7.10.2011, 13:51


--------------------
user posted image
PM MAIL ICQ   Вверх
boostcoder
Дата 7.10.2011, 13:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



mes, reflectpp::create() используется только в с++ коде. это библиотечная реализация.
далее, в той самой функции(которую будет создавать компилятор) которая создает объект одного типа, я буду генерить каст из указателей на void в нужный тип. и после этого передавать в конструктор.
если Вы об этом.

Добавлено @ 14:01
Цитата(kosmonaFFFt @  7.10.2011,  13:50 Найти цитируемый пост)
регистрация уже созданных объектов в ком-нибудь словаре по имени немного из другой области - обычно такая функциональность встречается в IOC контейнерах и к reflection отношения имеет мало, например в Java и C# в reflection такого нет...

это нужно для binding`а с++ кода с run-time скриптом. т.е. скрипт может обращаться к объектам созданным не им только в том случае, если эти объекты зареганы в мапе. сам же скрипт, будет регать все объекты которые создает.

Цитата(kosmonaFFFt @  7.10.2011,  13:50 Найти цитируемый пост)
во первых придется писать парсер

это меньшее о чем я беспокоюсь.

Цитата(kosmonaFFFt @  7.10.2011,  13:50 Найти цитируемый пост)
во вторых нарушается статичекая типизация C++

так в том то и смысл.

Цитата(kosmonaFFFt @  7.10.2011,  13:50 Найти цитируемый пост)
не лучше ли сделать вместо структуры rtti_ex и функций по работе с ней класс, например RttiEx, получать объект этого класса для типа и работать дальше с ними... Примерно так:

нет. rtti_ex_ - это внутренние структуры. они используются только внутрях всего этого дела.
юзер же работает с class_ и member_. смотрите: http://liveworkspace.org/code/f6f7dc0eb32d...a001570e37d93ec

Добавлено @ 14:01
Цитата(kosmonaFFFt @  7.10.2011,  13:50 Найти цитируемый пост)
классы RttiEx, Field, Method

rtti_ex_ у юзера не будет. будут class_ и member_.

Это сообщение отредактировал(а) boostcoder - 7.10.2011, 14:04
PM WWW   Вверх
mes
Дата 7.10.2011, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  7.10.2011,  12:53 Найти цитируемый пост)
юзер же работает с class_ и member_. смотрите: http://liveworkspace.org/code/f6f7dc0eb32d...a001570e37d93ec

только вот не компилится..

Добавлено через 1 минуту и 52 секунды
ну да ладно..



Код

struct member_ {
   member_type_ type() const {}
   const char* name() const {}
   size_t offset() const {}
   
   template<typename... Args>
   void invoke(void* ptr, const Args&... args) {std::cout<<__PRETTY_FUNCTION__<<std::endl;}
   

и зачем в динамическом методе нам шаблон ?!

Добавлено через 4 минуты и 52 секунды
Цитата(boostcoder @  7.10.2011,  12:49 Найти цитируемый пост)
Цитата

не связываете объекты с рантайм информацией..


+
Цитата

так объсните что я могу делать с void* , если тип задан в рантайме..


= Ваши предложения? 

ну вот например связка :
http://liveworkspace.org/code/5b558ca8d6b8...4616b3222f3422d

гарантирующая правильное создание удаление, и дополняется возможностью проверки совместимости типов.. 
ну и создание по имени то же не за горами smile




--------------------
PM MAIL WWW   Вверх
kosmonaFFFt
Дата 7.10.2011, 14:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 538
Регистрация: 14.4.2008
Где: Иннополис

Репутация: нет
Всего: 5



Цитата(boostcoder @  7.10.2011,  17:53 Найти цитируемый пост)
это нужно для binding`а с++ кода с run-time скриптом. т.е. скрипт может обращаться к объектам созданным не им только в том случае, если эти объекты зареганы в мапе. сам же скрипт, будет регать все объекты которые создает.

Извините за немного оффтоп... Вам рефлекшн нужен только для скриптинга? Просто по моему рефлекш к скриптингу имеет мало отношения, просто он может при этом использоваться, а может и не использоваться...


--------------------
user posted image
PM MAIL ICQ   Вверх
boostcoder
Дата 7.10.2011, 14:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  7.10.2011,  14:15 Найти цитируемый пост)
только вот не компилится..

lда. недописал, ибо некоторые моменты не ясны. собственно этим и занимаюсь.

Цитата(mes @  7.10.2011,  14:15 Найти цитируемый пост)
и зачем в динамическом методе нам шаблон ?!

его там не будет. по идее, там будет args_pack.

Цитата(mes @  7.10.2011,  14:15 Найти цитируемый пост)
ну вот например связка :
http://liveworkspace.org/code/5b558ca8d6b8...4616b3222f3422d

гарантирующая правильное создание удаление, и дополняется возможностью проверки совместимости типов.. 
ну и создание по имени то же не за горами

осмыслить нужно...

Добавлено через 2 минуты и 41 секунду
Цитата(kosmonaFFFt @  7.10.2011,  14:23 Найти цитируемый пост)
Вам рефлекшн нужен только для скриптинга?

нет. это предполагаемая финальная возможность.
основная же цель - привнести в с++ расширенную информацию о типах, плюс, динамические плюшки для операций с типами.

Добавлено через 11 минут и 16 секунд
Цитата(mes @  7.10.2011,  14:15 Найти цитируемый пост)
ну вот например связка :
http://liveworkspace.org/code/5b558ca8d6b8...4616b3222f3422d

понял. о чем-то подобном я писал выше. но я предполагал что rtti_ex_ должен содержать в себе указатели на функции, которые плагин будет генерить для каждого типа. и при инициализации глобального массива rtti_ex_ привязывать каждый элемент к своим функциям.
PM WWW   Вверх
mes
Дата 7.10.2011, 14:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  7.10.2011,  13:23 Найти цитируемый пост)
 но я предполагал что rtti_ex_ должен содержать в себе указатели на функции, которые плагин будет генерить для каждого типа. и при инициализации глобального массива rtti_ex_ привязывать каждый элемент к своим функциям. 

суть не в том, где и когда размещать таблицу функций, а в том, что каждый объект должен иметь указатель на свой тип, поэтому void* для передачи отменяется.. 



--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 7.10.2011, 14:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  7.10.2011,  14:42 Найти цитируемый пост)
а в том, что каждый объект должен иметь указатель на свой тип

ааа, ну да smile это позволит избавится от дополнительных двух карт.
т.е. каждый пользовательский тип нужно оборачивать во что-то типа object_t?

Это сообщение отредактировал(а) boostcoder - 7.10.2011, 14:53
PM WWW   Вверх
mes
Дата 7.10.2011, 14:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  7.10.2011,  13:49 Найти цитируемый пост)
ааа, ну да  это позволит избавится от дополнительных двух карт. 

вобще то  указатель  нужен не для этого smile


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 7.10.2011, 14:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  7.10.2011,  14:53 Найти цитируемый пост)
вобще то  указатель  нужен не для этого

или я "того", или сегодня не мой день smile 
не затруднит ли Вас объяснить на пальцах задумку? а то есть подозрение, что я все же чего-то недопонимаю...

Это сообщение отредактировал(а) boostcoder - 7.10.2011, 14:59
PM WWW   Вверх
mes
Дата 7.10.2011, 15:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Код

void f(void * o) {
   static_cast<A*>(o) ->do_some();
}

void f(object * o) 
{
   if (A  * a =  safe_cast<A*>(o))  a->do_some();
}

первый случай не безопасный, второй вполне smile 

safe_cast для чистого void* применить не получиться ..

Добавлено через 12 минут и 40 секунд
вот добавил созданиепо строковому имени : http://liveworkspace.org/code/d6ab67485b64...34102089de2a7bd


Это сообщение отредактировал(а) mes - 7.10.2011, 15:21


--------------------
PM MAIL WWW   Вверх
mes
Дата 7.10.2011, 15:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



вот с примитивной проверкой :
http://liveworkspace.org/code/622e0b0a7670...42bd1bc00f1f8be


--------------------
PM MAIL WWW   Вверх
mes
Дата 7.10.2011, 16:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



вот добавил примитивный инвокинг : http://liveworkspace.org/code/3821cf66d30d...a6d63c1cc5a270c
расширить для произвольного кол-ва аргументов проблем не составляет.. проблематично продумать правила конвертации и проверки совместимости типов.. 


Это сообщение отредактировал(а) mes - 7.10.2011, 16:15


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 7.10.2011, 16:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



разбираюсь.
PM WWW   Вверх
mes
Дата 7.10.2011, 22:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



вот еще один примерчик для разбора, как раз посвящен проблеме конвертации типов.. 
если продумать правила можно будет это дело автоматизировать :
http://liveworkspace.org/code/e40598e4dfb1...6d347046968ad29



--------------------
PM MAIL WWW   Вверх
Страницы: (10) [Все] 1 2 3 ... Последняя »
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.2504 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.