/* *****************************************************************************
* %{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;
}