Skip to content

Commit

Permalink
更多的宏,避免重复代码。
Browse files Browse the repository at this point in the history
  • Loading branch information
heroboy authored Aug 21, 2023
1 parent 2f4bdb3 commit d7d1bfc
Showing 1 changed file with 45 additions and 18 deletions.
63 changes: 45 additions & 18 deletions src/群友提交/第10题/494199.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
#include <iostream>
#include <utility>
namespace {
struct _init {
struct _any {
//为了更好看的扩展ints的语法
explicit _any(auto);

//convert to any
template<class T>
operator T();
};
Expand All @@ -10,7 +14,7 @@ namespace {
constexpr bool _can_size(std::integer_sequence<size_t, ints...> int_seq)
{
return (requires{
T{(ints, _init{})...};
T{ _any(ints)... };
});
}

Expand Down Expand Up @@ -45,30 +49,39 @@ namespace {
}
}

//为了能递归使用LOOP
//https://stackoverflow.com/a/12540675
# define EMPTY(...)
# define DEFER(...) __VA_ARGS__ EMPTY()
# define OBSTRUCT(...) __VA_ARGS__ DEFER(EMPTY)()
# define EXPAND(...) __VA_ARGS__

#define LOOP0(body,sep)
#define LOOP1(body,sep) body(0)
#define LOOP2(body,sep) LOOP1(body,sep) sep() body(1)
#define LOOP3(body,sep) LOOP2(body,sep) sep() body(2)
#define LOOP4(body,sep) LOOP3(body,sep) sep() body(3)
#define LOOP1(body,sep) body(1)
#define LOOP2(body,sep) body(2) sep() LOOP1(body,sep)
#define LOOP3(body,sep) body(3) sep() LOOP2(body,sep)
#define LOOP4(body,sep) body(4) sep() LOOP3(body,sep)

//LOOP(2) EXPAND TO: body(0) sep() body(1)
#define LOOP(n,body,sep) LOOP ## n(body,sep)

//从n到1的重复循环
//LOOP(n) EXPAND TO: body(n) sep() body(n-1) ... body(1)
#define LOOP(n,body,sep) LOOP ## n(body,sep)
#define LOOP_ID() LOOP

template<class T>
void for_each_member(const T& obj, auto&& f)
{
#define EMPTY()
//#define EMPTY()
#define COMMA() ,

//m0
//m0
#define MAKE_M_VAR(n) m##n
//f(m0)
#define MAKE_F_CALL(n) f(m##n)
//const auto& [m0, m1, m2, m3] = obj;
#define MAKE_UNPACK(n) const auto& [ LOOP(n,MAKE_M_VAR,COMMA) ] = obj
#define MAKE_UNPACK(n) const auto& [ DEFER(LOOP_ID)()(n,MAKE_M_VAR,COMMA) ] = obj
//f(m0), f(m1), f(m2), f(m3);
#define MAKE_CALL(n) LOOP(n, MAKE_F_CALL, COMMA);
#define MAKE_CALL(n) DEFER(LOOP_ID)()(n, MAKE_F_CALL, COMMA);

//MAKE_ALL_CHECK(4) EXPAND TO:
//if constexpr (size<T>() == 4)
Expand All @@ -83,10 +96,25 @@ void for_each_member(const T& obj, auto&& f)
MAKE_CALL(n);\
}

MAKE_ALL_CHECK(4);
MAKE_ALL_CHECK(3);
MAKE_ALL_CHECK(2);
MAKE_ALL_CHECK(1);
//这里LOOP被递归调用了

/*
expand to:
if constexpr (size<T>() == 4) {
const auto& [m4, m3, m2, m1] = obj; f(m4), f(m3), f(m2), f(m1);;
} if constexpr (size<T>() == 3) {
const auto& [m3, m2, m1] = obj; f(m3), f(m2), f(m1);;
} if constexpr (size<T>() == 2) {
const auto& [m2, m1] = obj; f(m2), f(m1);;
} if constexpr (size<T>() == 1) {
const auto& [m1] = obj; f(m1);;
};
*/
EXPAND(LOOP(4, MAKE_ALL_CHECK, EMPTY));




#undef MAKE_ALL_CHECK
#undef MAKE_CALL
Expand All @@ -106,11 +134,10 @@ int main() {

std::cout << size<X>() << '\n';
std::cout << size<Y>() << '\n';

auto print = [](const auto& member) {
std::cout << member << ' ';
};
for_each_member(x, print);
for_each_member(y, print);
}

0 comments on commit d7d1bfc

Please sign in to comment.