В LinkedIn встретил ссылку на реализацию тупла без использования рекурсии: тыц. Реализация активно эксплуатирует C++ный fold expression и std::integer_sequence. Вот прям отличная демонстрация того, как эти фичи могут (и должны?) применяться.
Еще очень удачно совпало, что ссылка эта попала мне на глаза вскоре после того, как я проделал в чем-то похожую работу. Правда, у меня ситуация была чуть сложнее, ведь в тупле все N полей присутствуют всегда, поэтому размер всех туплов одного типа одинаков и фиксирован. Тогда как в моем случае объекты могут состоять из разного набора полей, поэтому нужно размер каждого объекта определять индивидуально, да и расположение полей в каждом объекте может быть уникальным. Так что в своей реализации без метапрограммирования на базе рекурсии я не смог обойтись. Возможно, еще и потому, что у меня мало опыта с fold expression и std::integer_sequence.
Поэтому решил утащить к себе в склерозник кусочек чужого кода на память. Чтобы легче было найти когда потребуется.
Этот кусочек кода отвечает за подсчет расположения полей внутри объекта с учетом их правильного выравнивания. В результате своей работы функция calculate_positions возвращает std::array размером (N+1), где элементы 0..(N-1) содержат смещение i-го поля, а элемент N -- общий размер объекта.
Оригинал кода можно увидеть здесь, а вот чуть-чуть модифицированная мной версия:
template <class T> struct PositionWrapper {}; template <std::size_t _last, std::size_t... _is> struct Positions { static consteval auto to_array() { return std::array<std::size_t, sizeof...(_is) + 1>{_is..., _last}; } }; template <class T, std::size_t _last, std::size_t... _is> consteval auto operator+( const Positions<_last, _is...>& /*_sizes*/, const PositionWrapper<T>& /*_w*/) { if constexpr (_last % alignof(T) == 0) { constexpr auto last_new = _last + sizeof(T); return Positions<last_new, _is..., _last>{}; } else { constexpr auto last_corrected = (_last / alignof(T) + 1) * alignof(T); constexpr auto last_new = last_corrected + sizeof(T); return Positions<last_new, _is..., last_corrected>{}; } } template <class... Types> consteval auto calculate_positions() { return (Positions<0>{} + ... + PositionWrapper<Types>{}).to_array(); } |
2 комментария:
Евгений, дорогой! Прости что врываюсь из прошлого, видя твое (редкое) увлечение акустикой наушников, посоветуй закрытые наушники, которые играют ГРОМКО. Чтобы можно было слушать музыку громко когда все ушли спать, и не теребонькать бесконечно движок громкости, пытаясь сделать погромче. Ведь такая базовая потребность - сделать погромче, скажи КАК?
@Andrey
К сожалению, не могу подсказать :(
Мне подходят только вкладыши (и редкие модели внутриканальных затычек). В таких наушниках нет проблем с громкостью и с тем, что их звук мешает окружающим.
В телеграмме есть группа soundcheck39_chat, можно попробовать там спросить, там наверняка есть люди, через чьи руки прошло множество полноразмеров.
Отправить комментарий