сопоставление сигнатур
От: niXman Ниоткуда https://github.com/niXman
Дата: 27.10.17 08:59
Оценка:
привет!

к примеру, имеем такую функцию:
template<typename... Args>
yas::shared_buffer func(Args&&... args) {
    yas::mem_ostream os;
    yas::binary_oarchive<yas::mem_ostream, yas::binary> oa(os);
    oa & std::make_tuple(std::forward<Args>(args)...);
    return os.get_shared_buffer();
}

к примеру, вызываем ее с такими аргументами — func('a', 3, 4ull);, и получаем сериализованный архив.
на противоположной стороне пытаемся десериализовать архив в другие типы — что получим — зависит...

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

есть такой примитивный и дико оверхедный вариант: использовать __PRETTY_FUNCTION__, в рантайме из нее выделить только сигнатуру + подсчитать хешь от полученной строки.
и да, GCC говорит что __PRETTY_FUNCTION__ not a constant expression, хотя clang говорит что да.

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

какие мысли?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Отредактировано 27.10.2017 8:59 niXman . Предыдущая версия .
Re: сопоставление сигнатур
От: Кодт Россия  
Дата: 27.10.17 11:08
Оценка: 13 (2) +1
Здравствуйте, niXman, Вы писали:

X>какие мысли?


Смириться с рантаймом, — потому что вытащить __func__ в чистый компайлтайм может быть сложно.
Можно ускорить расчёт хешей через мемоизацию.
template<class... Args> size_t eval_types_hash() {
  return hash_value(__func__); // TODO: выдрать из буста hash_value(const (&char)[N])
}
template<class... Args> size_t types_hash() {
  static const size_t h = eval_types_hash<Args...>();
  return h;
}


Чтобы не хранить кучу строк, — можно разбить на типы
template<class Arg> size_t eval_type_hash() {
  return hash_value(__func__);
}
template<class Arg> size_t type_hash() {  // для часто используемых типов можно специализировать
  static const size_t h = eval_type_hash<Arg>();
  return h;
}

template<class... Args> size_t eval_types_hash() {
  return hash_value(initializer_list<size_t>{type_hash<Args>...});  // TODO: написать самому, если в бусте нет
}
template<class... Args> size_t types_hash() {
  static const size_t h = eval_types_hash<Args...>();
  return h;
}


Вот, наверно, как-то так.
Перекуём баги на фичи!
Re[2]: сопоставление сигнатур
От: niXman Ниоткуда https://github.com/niXman
Дата: 27.10.17 11:19
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Смириться с рантаймом, — потому что вытащить __func__ в чистый компайлтайм может быть сложно.

ну clang же умеет.

К> return hash_value(__func__); // TODO: выдрать из буста hash_value(const (&char)[N])

не нужно из буста, есть же: https://gist.github.com/niXman/e12d185894e6c09d0d0df46eabebbf27


спасибо, думаю...
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Отредактировано 27.10.2017 11:19 niXman . Предыдущая версия .
Re[3]: сопоставление сигнатур
От: Кодт Россия  
Дата: 27.10.17 15:17
Оценка: 7 (1)
Здравствуйте, niXman, Вы писали:

К>>Смириться с рантаймом, — потому что вытащить __func__ в чистый компайлтайм может быть сложно.

X>ну clang же умеет.

Не "умеет", а "хочет".
Почему-то у gcc макрос __FILE__ реализован как строковый литерал, а семейство __FUNCTION__ — как константные массивы (к которым gcc, наверно, забыл прикрутить constexpr).
Возможно, что это в угоду какой-нибудь дробной линковке, наподобие того, как у VC сделано edit-n-continue с макросом __LINE__.
Перекуём баги на фичи!
Re[2]: сопоставление сигнатур
От: Кодт Россия  
Дата: 27.10.17 15:19
Оценка:
<>

только не __func__, а __PRETTY_FUNCTION__, конечно. Чтобы типы в текст пролезли.
Перекуём баги на фичи!
Re[4]: сопоставление сигнатур
От: niXman Ниоткуда https://github.com/niXman
Дата: 27.10.17 15:47
Оценка: 7 (1)
Здравствуйте, Кодт, Вы писали:

К>... семейство __FUNCTION__ — как константные массивы (к которым gcc, наверно, забыл прикрутить constexpr).

не забыл, а несделали намеренно.
недавно в GCC ML была эта тема. кто-то таки спрашивал, почему есть что есть, а в кланге — констекспр? так разрабы ответили, что в стандарте так написано, иначе — самодеятельность. и предложили написать пропосал.
и при этом признали, что пофиксить — просто, и никакая обратная совместимость не сломается.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Отредактировано 27.10.2017 16:00 niXman . Предыдущая версия . Еще …
Отредактировано 27.10.2017 15:49 niXman . Предыдущая версия .
Re[3]: сопоставление сигнатур
От: niXman Ниоткуда https://github.com/niXman
Дата: 27.10.17 16:01
Оценка:
Здравствуйте, Кодт, Вы писали:

К>только не __func__, а __PRETTY_FUNCTION__, конечно. Чтобы типы в текст пролезли.

та понятно)
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re: сопоставление сигнатур
От: Alexander G Украина  
Дата: 28.10.17 11:53
Оценка:
Здравствуйте, niXman, Вы писали:

X>какие мысли?


struct S<auto... args> {};

typeid(S<Args...>)

?
Русский военный корабль идёт ко дну!
Re[2]: сопоставление сигнатур
От: niXman Ниоткуда https://github.com/niXman
Дата: 28.10.17 12:00
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>typeid(S<Args...>)


typeid() же непереносим. об этом я, помоему, впервую очередь подумал..
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re: сопоставление сигнатур
От: YuriV  
Дата: 29.10.17 23:26
Оценка: 86 (2) +1
Здравствуйте, niXman, Вы писали:

X>есть такой примитивный и дико оверхедный вариант: использовать __PRETTY_FUNCTION__, в рантайме из нее выделить только сигнатуру + подсчитать хешь от полученной строки.

X>и да, GCC говорит что __PRETTY_FUNCTION__ not a constant expression, хотя clang говорит что да.

X>какие мысли?


Может быть так:
https://github.com/Manu343726/ctti
https://github.com/Manu343726/ctti/blob/master/include/ctti/detail/pretty_function.hpp
Re[3]: сопоставление сигнатур
От: Кодт Россия  
Дата: 30.10.17 08:58
Оценка: 7 (1)
Здравствуйте, niXman, Вы писали:

X>typeid() же непереносим. об этом я, помоему, впервую очередь подумал..


Больше того, идентификаторы (числовые и хеши, в том числе) у type_info могут меняться от запуска к запуску. Это оговорено в стандарте.
Перекуём баги на фичи!
Re[4]: сопоставление сигнатур
От: niXman Ниоткуда https://github.com/niXman
Дата: 30.10.17 09:19
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Больше того, идентификаторы (числовые и хеши, в том числе) у type_info могут меняться от запуска к запуску. Это оговорено в стандарте.

ужос какой %)
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[2]: сопоставление сигнатур
От: niXman Ниоткуда https://github.com/niXman
Дата: 30.10.17 09:20
Оценка:
Здравствуйте, YuriV, Вы писали:

YV>Может быть так:

YV>https://github.com/Manu343726/ctti
YV>https://github.com/Manu343726/ctti/blob/master/include/ctti/detail/pretty_function.hpp

хорошая идея, во только оно не собирается: https://github.com/Manu343726/ctti/issues/19
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re: сопоставление сигнатур
От: kov_serg Россия  
Дата: 30.10.17 09:39
Оценка:
Здравствуйте, niXman, Вы писали:

X>к примеру, вызываем ее с такими аргументами — func('a', 3, 4ull);, и получаем сериализованный архив.

X>на противоположной стороне пытаемся десериализовать архив в другие типы — что получим — зависит...

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


Может стоит подойти с другой стороны и иметь формат сериализуемой структуры. И по этому формату генерировать код сереализаци, десериализации, справку и проверку валидности и полноты данных? serialize_using(PUBLIC_FORMAT_1).store('a',3,4ull);
Re[2]: сопоставление сигнатур
От: niXman Ниоткуда https://github.com/niXman
Дата: 30.10.17 09:56
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Может стоит подойти с другой стороны и иметь формат сериализуемой структуры. И по этому формату генерировать код сереализаци, десериализации, справку и проверку валидности и полноты данных? serialize_using(PUBLIC_FORMAT_1).store('a',3,4ull);


так я это и пытаюсь сделать:
template<typename... Args>
yas::shared_buffer func(Args&&... args) {
    yas::mem_ostream os;
    yas::binary_oarchive<yas::mem_ostream, yas::binary> oa(os);
    oa & make_public_format<typename std::decay<Args>::type...>() // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
       & std::make_tuple(std::forward<Args>(args)...)
    ;
    return os.get_shared_buffer();
}


сейчас в проекте около 300 АПИшек, из них ~120 публичных, остальные для общения сервисов между собой. координально что-то изменять ооочень не хочется...
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Отредактировано 30.10.2017 9:59 niXman . Предыдущая версия . Еще …
Отредактировано 30.10.2017 9:59 niXman . Предыдущая версия .
Re[3]: сопоставление сигнатур
От: YuriV  
Дата: 30.10.17 16:22
Оценка:
Здравствуйте, niXman, Вы писали:

X>Здравствуйте, YuriV, Вы писали:


YV>>Может быть так:

YV>>https://github.com/Manu343726/ctti
YV>>https://github.com/Manu343726/ctti/blob/master/include/ctti/detail/pretty_function.hpp

X>хорошая идея, во только оно не собирается: https://github.com/Manu343726/ctti/issues/19


Мне когда-то надо было знать имя типа без rtti, потом надобность отпала и я даже не проверял.
Начиналось всё вот с этого:
https://stackoverflow.com/questions/35941045/can-i-obtain-c-type-names-in-a-constexpr-way
Re[3]: сопоставление сигнатур
От: PM  
Дата: 30.10.17 22:31
Оценка:
Здравствуйте, niXman, Вы писали:

YV>>Может быть так:

YV>>https://github.com/Manu343726/ctti
YV>>https://github.com/Manu343726/ctti/blob/master/include/ctti/detail/pretty_function.hpp

X>хорошая идея, во только оно не собирается: https://github.com/Manu343726/ctti/issues/19


Если достаточно только получить имя типа в runtime, то я использую упрощенную версию: https://github.com/pmed/v8pp/blob/master/v8pp/utility.hpp#L235
Re[4]: сопоставление сигнатур
От: ffk  
Дата: 31.10.17 09:54
Оценка:
Здравствуйте, PM, Вы писали:

PM>Здравствуйте, niXman, Вы писали:


YV>>>Может быть так:

YV>>>https://github.com/Manu343726/ctti
YV>>>https://github.com/Manu343726/ctti/blob/master/include/ctti/detail/pretty_function.hpp

X>>хорошая идея, во только оно не собирается: https://github.com/Manu343726/ctti/issues/19


PM>Если достаточно только получить имя типа в runtime, то я использую упрощенную версию: https://github.com/pmed/v8pp/blob/master/v8pp/utility.hpp#L235


Интересная наработка, но для различных компиляторов, type_id() возвращает разное строковое представление, т.е. для сериализации не подойдет.
Например, type_id<void(long)>().name() получается: "void (long)" clang, "void(long int)" gcc и "void(long)" msvc
Re[5]: сопоставление сигнатур
От: Кодт Россия  
Дата: 31.10.17 13:16
Оценка:
Здравствуйте, niXman, Вы писали:

X>недавно в GCC ML была эта тема. кто-то таки спрашивал, почему есть что есть, а в кланге — констекспр? так разрабы ответили, что в стандарте так написано, иначе — самодеятельность. и предложили написать пропосал.


8.4 Function definitions [dcl.fct.def]

8.4.1 In general [dcl.fct.def.general]


8 The function-local predefined variable __func__ is defined as if a definition of the form
static const char __func__[] = "function-name ";


И что интересно, специально сделали оговорку для эмуляции констекспра

14.3.2 Template non-type arguments [temp.arg.nontype]

1 If the type of a template-parameter contains a placeholder type (7.1.7.4, 14.1), the deduced parameter type is
determined from the type of the template-argument by placeholder type deduction (7.1.7.4.1). If a deduced
parameter type is not permitted for a template-parameter declaration (14.1), the program is ill-formed.
2 A template-argument for a non-type template-parameter shall be a converted constant expression (5.20) of
the type of the template-parameter. For a non-type template-parameter of reference or pointer type, the
value of the constant expression shall not refer to (or for a pointer type, shall not be the address of):
(2.1) — a subobject (1.8),
(2.2) — a temporary object (12.2),
(2.3) — a string literal (2.13.5),
(2.4) — the result of a typeid expression (5.2.8), or
(2.5) — a predefined __func__ variable (8.4.1).


Но тут следует заметить, что макросы __FUNCTION__ и __PRETTY_FUNCTION__ в стандарте отсутствуют вообще. И вот их вполне могли сделать настоящим констекспром, без отмахиваний "пишите пропозал".
Перекуём баги на фичи!
Re[5]: сопоставление сигнатур
От: PM  
Дата: 02.11.17 05:53
Оценка:
Здравствуйте, ffk, Вы писали:
PM>>Если достаточно только получить имя типа в runtime, то я использую упрощенную версию: https://github.com/pmed/v8pp/blob/master/v8pp/utility.hpp#L235

ffk>Интересная наработка, но для различных компиляторов, type_id() возвращает разное строковое представление, т.е. для сериализации не подойдет.

ffk>Например, type_id<void(long)>().name() получается: "void (long)" clang, "void(long int)" gcc и "void(long)" msvc

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