#include <ylt/struct_pack.hpp>
#include "template.h"
struct person {
    int64_t id;
    std::string name;
    int age;
    double salary;
};
//STRUCT_PACK_REFL(person, ID, name, age);
inline person& STRUCT_PACK_REFL_FLAG(person& t) {
    return t;
} 
template<typename T> constexpr std::size_t STRUCT_PACK_FIELD_COUNT_IMPL();
template<> constexpr std::size_t STRUCT_PACK_FIELD_COUNT_IMPL<person>() {
    return 3;
} 
inline decltype(auto) STRUCT_PACK_FIELD_COUNT(const person&) {
    return std::integral_constant<std::size_t, 3>{};
} 
template<std::size_t I> auto& STRUCT_PACK_GET(person& c) {
    if constexpr (0 == I) {
        return c.age;
    } if constexpr (1 == I) {
        return c.name;
    } if constexpr (2 == I) {
        return c.ID;
    }
    else {
        static_assert(I < STRUCT_PACK_FIELD_COUNT_IMPL<person>());
    }
} 
template<std::size_t I> const auto& STRUCT_PACK_GET(const person& c) {
    if constexpr (0 == I) {
        return c.age;
    } if constexpr (1 == I) {
        return c.name;
    } if constexpr (2 == I) {
        return c.ID;
    }
    else {
        static_assert(I < STRUCT_PACK_FIELD_COUNT_IMPL<person>());
    }
} 
inline auto& STRUCT_PACK_GET_0(person& c) {
    return STRUCT_PACK_GET<STRUCT_PACK_FIELD_COUNT_IMPL<person>() - 1 - 0>(c);
} 
inline auto& STRUCT_PACK_GET_1(person& c) {
    return STRUCT_PACK_GET<STRUCT_PACK_FIELD_COUNT_IMPL<person>() - 1 - 1>(c);
} 
inline auto& STRUCT_PACK_GET_2(person& c) {
    return STRUCT_PACK_GET<STRUCT_PACK_FIELD_COUNT_IMPL<person>() - 1 - 2>(c);
} 
inline const auto& STRUCT_PACK_GET_0(const person& c) {
    return STRUCT_PACK_GET<STRUCT_PACK_FIELD_COUNT_IMPL<person>() - 1 - 0>(c);
} 
inline const auto& STRUCT_PACK_GET_1(const person& c) {
    return STRUCT_PACK_GET<STRUCT_PACK_FIELD_COUNT_IMPL<person>() - 1 - 1>(c);
} 
inline const auto& STRUCT_PACK_GET_2(const person& c) {
    return STRUCT_PACK_GET<STRUCT_PACK_FIELD_COUNT_IMPL<person>() - 1 - 2>(c);
};
int main() {
    person person1{ .id = 1, .name = "hello struct pack", .age = 20, .salary = 1024.42 };

    using type = remove_cvref_t<decltype(person1)>;
    auto c1 = members_count<type>;
    int c2 = members_count_impl<type>();
    int c3 = detail::members_count<type>();

    auto id = detail::get_type_id<type>();
    auto t1 = type_struct<type>;
    auto t2 = type_string<decltype(person1.name)>;
    auto t3 = type_u32<decltype(person1.age)>;

    visit_struct_info<decltype(person1)>(person1);
    visit_member_info<>(person1.name, person1.age);

    auto sz_info = detail::calculate_payload_size(person1);
    // 1行代码序列化
    vector<char> buffer = serialize(person1);

    // 只反序列化person的第2个字段
    auto name = get_field<person, 1>(buffer.data(), buffer.size());
    cout << "hello " << name.value() << "Count == " << c1;
}