#include <vector>
#include <tuple>
#include <cstring>
#include <cstddef>
#include <iostream>
#include <exception>
#include <cassert>
#include <type_traits>
/* ------------------------------------------------ */
struct data_t {
char field1[10];
char field2[20];
char field3[30];
};
const char *getData(const char *key);
const char *field_keys[] = { "key1", "key2", "key3" };
/* --------------------------------------------------------- */
const char *getData(const char *key)
{
static const char ret[] = "1234567890123456789012345678901234567890";
return ret;
}
/* --------------------------------------------------------- */
std::size_t mystrlcpy(char *to, const char *from, std::size_t max)
{
if (to == NULL) {
throw std::runtime_error(std::string{} + __func__ + "to is NULL");
}
if (from == NULL) {
throw std::runtime_error(std::string{} + __func__ + "from is NULL");
}
char * const to0 = to;
if (max == 0)
return 0;
while (--max != 0 && *from) {
*to++ = *from++;
}
*to = '\0';
return to0 - to - 1;
}
/* implementation 1 --------------------------------------------------------- */
struct Map {
const char *key;
std::size_t offset;
std::size_t size;
};
static_assert(std::is_pod<data_t>::value, "");
std::vector<Map> map = {
{ field_keys[0], offsetof(data_t, field1), sizeof(data_t::field1), },
{ field_keys[1], offsetof(data_t, field2), sizeof(data_t::field2), },
{ field_keys[2], offsetof(data_t, field3), sizeof(data_t::field3), },
};
void test_1()
{
data_t data;
for (auto const& it : map) {
mystrlcpy(reinterpret_cast<char*>(&data) + it.offset, getData(it.key), it.size);
}
std::cout << data.field1 << std::endl;
std::cout << data.field2 << std::endl;
std::cout << data.field3 << std::endl;
}
/* implementation 2 --------------------------------------------------------- */
struct Map2 {
static constexpr std::size_t max = sizeof(field_keys)/sizeof(*field_keys);
Map2(data_t* pnt) : mpnt(pnt) {}
char* getDest(std::size_t num) {
std::array<char*, max> arr = {
mpnt->field1,
mpnt->field2,
mpnt->field3,
};
return arr[num];
}
const char* getKey(std::size_t num) {
return field_keys[num];
}
std::size_t getSize(std::size_t num) {
std::array<std::size_t, max> arr = {
sizeof(mpnt->field1),
sizeof(mpnt->field2),
sizeof(mpnt->field3),
};
return arr[num];
}
private:
data_t * const mpnt;
};
void test_2()
{
data_t data;
Map2 m(&data);
for (std::size_t i = 0; i < m.max; ++i) {
mystrlcpy(m.getDest(i), getData(m.getKey(i)), m.getSize(i));
}
std::cout << data.field1 << std::endl;
std::cout << data.field2 << std::endl;
std::cout << data.field3 << std::endl;
}
/* ---------------------------------------------------------------- */
int main() {
test_1();
test_2();
}