/* ***************************************************************************** * %{QMAKE_PROJECT_NAME} * Copyright (c) %YEAR% killerbee * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ****************************************************************************/ #include #include #include #include #include #include struct [[gnu::packed]] data { int a; double b; int c; }; static_assert(sizeof(data) == 16, "no padding"); template struct packed_storage { private: constexpr static inline auto Size = sizeof(T); std::byte data[Size]; void write(T x) { std::memcpy(data, &x, Size); } T read() const { T x; std::memcpy(&x, data, Size); return x; } public: packed_storage() = default; packed_storage(T x) { write(x); } packed_storage(const packed_storage&) = default; packed_storage& operator=(T x) & { write(x); return *this; } packed_storage& operator=(const packed_storage&) & = default; operator T() const { return read(); } }; struct data_2 { packed_storage a; packed_storage b; packed_storage c; }; template using packed_tuple = std::tuple...>; static_assert(sizeof(data) == sizeof(data_2)); static_assert(sizeof(packed_tuple) == sizeof(data)); // data_2 is an implicit lifetime type: static_assert(std::is_aggregate_v); static_assert(std::is_trivially_default_constructible_v); static_assert(std::is_trivially_copyable_v); static_assert(std::is_trivially_destructible_v); template struct sum_first_n; template struct sum_first_n : sum_first_n {}; template struct sum_first_n<0, R, Ns...> : std::integral_constant {}; template struct sum_first_n<0, R, F, Ns...> : std::integral_constant {}; static_assert(sum_first_n<0, 0>{} == 0); static_assert(sum_first_n<0, 0, 0>{} == 0); static_assert(sum_first_n<1, 0, 0>{} == 0); static_assert(sum_first_n<0, 1>{} == 1); static_assert(sum_first_n<0, 1, 0>{} == 1); static_assert(sum_first_n<0, 1, 1>{} == 1); static_assert(sum_first_n<1, 0, 1>{} == 1); static_assert(sum_first_n<4, 0, 1, 2, 3, 4, 5, 6>{} == 10); static_assert(not kblib::metafunction_success>{}); static_assert(kblib::metafunction_success>{}); template struct partial_sums; template struct partial_sums, std::index_sequence> : std::index_sequence::value...> { using type = std::index_sequence::value...>; }; template using partial_sums_for = partial_sums, std::make_index_sequence>; static_assert( std::is_same_v, partial_sums_for<0>::type>); template struct print_t; // print_t::type> x; static_assert( std::is_same::type, std::index_sequence<0>>::value); static_assert(std::is_same::type, std::index_sequence<0, 1, 3, 6>>::value); static_assert(std::is_same::type, std::index_sequence<0, 4, 12>>::value); template struct Member {}; template struct packed_reference {}; int packed_main(int, char**) { data d{42, 42.0, 654231}; d.a = 1; std::cout << d.b << '\n'; data_2 d2{42, 42.0, 654231}; d2.a = 1; std::cout << d2.b << '\n'; unsigned char buffer[]{ "\x2A\x0\x0\x0" // int a "\x0\x0\x0\x0\x0\x0\x45\x40" // double b (unaligned) "\x97\xFB\x9\x0" // int c }; return 0; }