@@ -63,61 +63,37 @@ double value_d = speed_of_light * 2.0;
6363
6464
6565# More advanced usage
66- You can forget about the order of parameters in your code. Complete code see: [ godbolt] ( https://godbolt.org/z/K8fqjqs34 )
66+ You can forget about the order of parameters in your code. Complete code see: [ godbolt] ( https://godbolt.org/z/K4r9d9far )
6767
6868``` c++
69- namespace Tag { struct Rho{}; struct Theta{}; struct Phi{};}
70-
7169using rho_type = boxed::boxed<double ,Tag::Rho>;
7270using theta_type = boxed::boxed<double ,Tag::Theta>;
7371using phi_type = boxed::boxed<double ,Tag::Phi>;
7472
73+ template <typename ... F>
74+ struct overload : F...{ using F::operator()...;};
7575
76- template<typename ...T>
77- struct Wrap {};
76+ template<typename... Ts> overload(Ts...) -> overload<Ts...>;
7877
79- template<typename T, typename ...Rest >
80- struct Wrap <T, Rest ...>
78+ template<typename... Ts >
79+ struct Wrap
8180{
81+ overload<Ts...> func_wrap;
8282
83- constexpr static inline std::size_t n = 1 + sizeof...(Rest);
84- using fun_type = std::function<double(T)>;
85- Wrap(fun_type&& first, std::function<double(Rest)>&& ...rest)
86- : first(std::forward<fun_type>(first))
87- , rest(std::forward<std::function<double(Rest)>>(rest)...)
88- {}
89-
90- const fun_type first;
91- Wrap<Rest...> rest;
92-
93- auto operator()(T v)
94- {
95- return first(v);
96- }
97-
98- template<typename F>
99- requires (!std::is_same_v<T,F>)
100- decltype(auto) operator()(F v)
101- {
102- return rest(v);
103- }
83+ Wrap (Ts... funcs): func_wrap(funcs...){}
10484
105-
106- template<typename ...Args>
107- requires (!std::derived_from<all_different<typename std::decay<Args>::type...>, std::false_type>)
108- decltype(auto) operator()(Args &&... args)
85+ template<typename... Args>
86+ auto operator()(Args... args)
10987 {
110- static_assert( (sizeof...(Args) == n) );
111- return ( operator()(std::forward<Args>(args)) * ... );
88+ return (func_wrap(args)*...);
11289 }
11390};
11491
115- auto x_coord = Wrap<rho_type,theta_type,phi_type>{
116- [ ] (rho_type rho){ return unbox(rho); },
117- [ ] (theta_type theta){ return sin(unbox(theta)); },
118- [ ] (phi_type phi){ return cos(unbox(phi)); }
119- };
12092
93+ auto x_coord = Wrap([ ] (rho_type rho){ return unbox(rho); },
94+ [ ] (theta_type theta){ return sin(unbox(theta)); },
95+ [ ] (phi_type phi){ return cos(unbox(phi)); }
96+ );
12197
12298int main()
12399{
@@ -127,6 +103,7 @@ int main()
127103
128104 assert(x_coord(rho,theta,phi) == x_coord(theta,rho,phi));
129105 assert(x_coord(rho,theta,phi) == x_coord(phi,rho,theta));
106+ assert(x_coord(rho,theta,phi) == x_coord(phi,rho,theta));
130107}
131108```
132109
0 commit comments