к примеру, вызываем ее с такими аргументами — func('a', 3, 4ull);, и получаем сериализованный архив.
на противоположной стороне пытаемся десериализовать архив в другие типы — что получим — зависит...
вопрос в том, как на стороне сериализации аргументов создать некий идентификатор сигнатуры, чтоб сериализовать его в архив перед аргументами, и проверять соответствие на противоположной стороне.
есть такой примитивный и дико оверхедный вариант: использовать __PRETTY_FUNCTION__, в рантайме из нее выделить только сигнатуру + подсчитать хешь от полученной строки.
и да, GCC говорит что __PRETTY_FUNCTION__ not a constant expression, хотя clang говорит что да.
ну...есть еще несколько вариантов, типа создания для стандартных типов ассоциированных ID, и добавления списка этих ID`ов в архив. но не хочется иметь гимор в виде ручного задания ассоциации для каждого нестандартного типа.
какие мысли?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, Кодт, Вы писали:
К>Смириться с рантаймом, — потому что вытащить __func__ в чистый компайлтайм может быть сложно.
ну clang же умеет.
К> return hash_value(__func__); // TODO: выдрать из буста hash_value(const (&char)[N])
не нужно из буста, есть же: https://gist.github.com/niXman/e12d185894e6c09d0d0df46eabebbf27
спасибо, думаю...
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, niXman, Вы писали:
К>>Смириться с рантаймом, — потому что вытащить __func__ в чистый компайлтайм может быть сложно. X>ну clang же умеет.
Не "умеет", а "хочет".
Почему-то у gcc макрос __FILE__ реализован как строковый литерал, а семейство __FUNCTION__ — как константные массивы (к которым gcc, наверно, забыл прикрутить constexpr).
Возможно, что это в угоду какой-нибудь дробной линковке, наподобие того, как у VC сделано edit-n-continue с макросом __LINE__.
Здравствуйте, Кодт, Вы писали:
К>... семейство __FUNCTION__ — как константные массивы (к которым gcc, наверно, забыл прикрутить constexpr).
не забыл, а несделали намеренно.
недавно в GCC ML была эта тема. кто-то таки спрашивал, почему есть что есть, а в кланге — констекспр? так разрабы ответили, что в стандарте так написано, иначе — самодеятельность. и предложили написать пропосал.
и при этом признали, что пофиксить — просто, и никакая обратная совместимость не сломается.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, niXman, Вы писали:
X>есть такой примитивный и дико оверхедный вариант: использовать __PRETTY_FUNCTION__, в рантайме из нее выделить только сигнатуру + подсчитать хешь от полученной строки. X>и да, GCC говорит что __PRETTY_FUNCTION__ not a constant expression, хотя clang говорит что да.
X>какие мысли?
Здравствуйте, Кодт, Вы писали:
К>Больше того, идентификаторы (числовые и хеши, в том числе) у type_info могут меняться от запуска к запуску. Это оговорено в стандарте.
ужос какой %)
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, niXman, Вы писали:
X>к примеру, вызываем ее с такими аргументами — func('a', 3, 4ull);, и получаем сериализованный архив. X>на противоположной стороне пытаемся десериализовать архив в другие типы — что получим — зависит...
X>вопрос в том, как на стороне сериализации аргументов создать некий идентификатор сигнатуры, чтоб сериализовать его в архив перед аргументами, и проверять соответствие на противоположной стороне.
Может стоит подойти с другой стороны и иметь формат сериализуемой структуры. И по этому формату генерировать код сереализаци, десериализации, справку и проверку валидности и полноты данных? serialize_using(PUBLIC_FORMAT_1).store('a',3,4ull);
Здравствуйте, kov_serg, Вы писали:
_>Может стоит подойти с другой стороны и иметь формат сериализуемой структуры. И по этому формату генерировать код сереализаци, десериализации, справку и проверку валидности и полноты данных? serialize_using(PUBLIC_FORMAT_1).store('a',3,4ull);
сейчас в проекте около 300 АПИшек, из них ~120 публичных, остальные для общения сервисов между собой. координально что-то изменять ооочень не хочется...
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Интересная наработка, но для различных компиляторов, type_id() возвращает разное строковое представление, т.е. для сериализации не подойдет.
Например, type_id<void(long)>().name() получается: "void (long)" clang, "void(long int)" gcc и "void(long)" msvc
Здравствуйте, 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 ";
И что интересно, специально сделали оговорку для эмуляции констекспра
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__ в стандарте отсутствуют вообще. И вот их вполне могли сделать настоящим констекспром, без отмахиваний "пишите пропозал".
Здравствуйте, 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
Да, точно, непереносимо и для сериализации не подойдет.
Здравствуйте, niXman, Вы писали:
X>Здравствуйте, Chorkov, Вы писали:
C>>my_typeid<std::map<int8_t, int32_t>>::id == my_typeid<std::map<int32_t, int8_t>>::id
X>кстати да... X>так как же суммировать хеши?
Если бы не constexpr, я бы посоветовал boost::hash_combine.
А так, можно умножить на простые числа: