diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25410\351\242\230/akchilov2.cpp" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25410\351\242\230/akchilov2.cpp" new file mode 100644 index 00000000..1f7ed006 --- /dev/null +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25410\351\242\230/akchilov2.cpp" @@ -0,0 +1,218 @@ +#include +#include +#include +#include +#include + +//需要C++20以上 +//msvc下可以编译 +//这个程序的原理是用std::is_constructible猜测类的成员类型 +//然后使用偏移量来访问类的数据成员 +namespace my_utilities +{ + struct inits + { + template operator T(); + }; + + //这个类型用来试探某种类型是不是类的第N个成员类型 + //由于std::is_constructible隐式转换也会true,所以这里禁止隐式转换 + //以求结果精确 + template struct convert_forbid + { + using type = T; + template< + class U, + class En = std::enable_if_t> + > operator U(); + }; + //计算成员数量 + template struct count_size + { + static constexpr size_t value = cnt; + }; + template class construct_list, size_t cnt, class First, class ...rest> + struct count_size, cnt> + { + static constexpr size_t value = + count_size< + std::is_constructible_v, + T, + construct_list, + (std::is_constructible_v ? cnt : cnt - 1)> + ::value; + }; + //工具类,选择类型分支 + //本来我想用type_traits里面的,不熟悉就没用 + template struct select_impl + { + using type = A; + }; + + template struct select_impl + { + using type = B; + }; + template using select_branch = typename select_impl::type; + + template struct add_front {}; + template class TL, class...Args> struct add_front> + { + using type = TL; + }; + + template struct gen_list + {}; + + template class TL, class ...Args> struct gen_list<0, T, TL> + { + using type = TL; + }; + + template class TL, class T, class ...Args> struct gen_list> + { + using type = typename gen_list>::type; + }; + + + + template struct replace_at + { + }; + + template class pre, template class bck, class RP, class bck_first, class ...preargs, class... bckargs> + struct replace_at, bck, RP> + { + using type = typename replace_at, bck, RP>::type; + }; + + template class pre, template class bck, class RP, class bck_first, class ...preargs, class... bckargs> + struct replace_at<0, pre, bck, RP> + { + using type = pre; + }; + + template class Name> struct as_ {}; + templateclass TL, templateclass Name, class ...Args> struct as_, Name> + { + using type = Name; + }; + template struct tl {}; + + //在列表种选择元素 + //懒得写了,骗一下这个tuple_element_t + template struct select_element { using type = std::tuple_element_t::type>; }; + +} +using namespace my_utilities; + + +template constexpr size_t size() +{ + return count_size, tl, 10>::value; +} + + +//工具类,测试T的N个成员是否为Mem_type +template struct is_constructible_at +{ + using construct_list = typename gen_list(), inits, tl>::type; + using chk_constructible = typename replace_at, construct_list, convert_forbid>::type; + + using constructible_type = typename as_::type; + static constexpr bool value = constructible_type::value; + +}; +//工具类,用一个列表mem_type_list逐个测试is_constructilbe_at,得到T的第N个成员的类型 +template struct constructible_at_try {}; +template class mem_type_list, class first, class ...Args> +struct constructible_at_try> +{ + static constexpr bool cstible = is_constructible_at::value; + using type = typename constructible_at_try, mem_type_list + > + >::type; +}; + +template class mem_type_list, class first, class ...Args> struct constructible_at_try> +{ + using type = first; +}; +//工具类,生成成员列表 +template struct make_construct_list +{}; +template class TL, template class saved, class ...Args, class ...savedArgs> struct make_construct_list<0, T, TL, saved> +{ + using current_type = typename constructible_at_try>::type; + using type = typename add_front>::type; +}; +template class saved, class TL, class ...Args> struct make_construct_list> +{ + using current_type = typename constructible_at_try::type; + using type = typename make_construct_list>::type; +}; + + +//计算偏移 +template class TL, class ...Typs> constexpr auto make_offset_list(TL) +{ + return std::array{ (sizeof(Typs) % pack_size ? sizeof(Typs) / pack_size * pack_size + pack_size : sizeof(Typs))... }; +} + + +template class offset_pointer +{ + using construct_list = typename make_construct_list() - 1, T, possibilities, tl<>>::type; +public: + offset_pointer(T a) noexcept : baseptr(reinterpret_cast(&a)) {} + template typename select_element::type get() const + { + if constexpr (I == 0) { + return *(reinterpret_cast::type>>(baseptr)); + } + else + { + return *( + reinterpret_cast::type>>( + baseptr + std::accumulate(member_offset.begin() + 1, member_offset.begin() + 1 + I, 0) + ) + ); + } + } +private: + unsigned char* baseptr; + std::array()> + member_offset{ + make_offset_list(typename make_construct_list() - 1, T, possibilities, tl<>>::type()) + }; +}; + +//理论上可以算内存对齐,但是已经太长了,不想写那个了 +template void for_each_member_impl(T&& t, F&& f, std::index_sequence) +{ + //有点上帝视角了,因为已经看到了所有的数据类型 + using possible_types = tl; + offset_pointer op{ t }; + (f(op.template get()), ...); +} + +template constexpr void for_each_member(T&& t, F&& f) +{ + for_each_member_impl(std::move(t), std::move(f), std::make_index_sequence()>{}); +} + +int main() { + struct X { std::string s{ " " }; }x; + struct Y { double a{}, b{}, c{}, d{}; }y; + std::cout << size() << '\n'; + std::cout << size() << '\n'; + + auto print = [](const auto& member) { + std::cout << member << ' '; + }; + for_each_member(x, print); + for_each_member(y, print); +}