@@ -63,46 +63,70 @@ 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
66+ You can forget about the order of parameters in your code. Complete code see: [ godbolt ] ( https://godbolt.org/z/K8fqjqs34 )
6767
6868``` c++
69- # include < boxed-cpp/boxed.hpp >
69+ namespace Tag { struct Rho{}; struct Theta{}; struct Phi{};}
7070
71- // Create unique structures
72- namespace tags { struct Speed{}; struct Permittivity{}; struct Permeability{}; }
71+ using rho_type = boxed::boxed<double,Tag::Rho>;
72+ using theta_type = boxed::boxed<double,Tag::Theta>;
73+ using phi_type = boxed::boxed<double,Tag::Phi>;
7374
74- using Speed = boxed::boxed<double, tags::Speed>;
75- using Permittivity = boxed::boxed<double, tags::Permittivity>;
76- using Permeability = boxed::boxed<double, tags::Permeability>;
7775
78- Speed wave_speed_inside(Permittivity epsilon, Permeability mu)
79- {
80- return Speed(1.0 / std::sqrt(unbox(epsilon) * unbox(mu)));
81- };
76+ template<typename ...T>
77+ struct Wrap {};
8278
83- template <typename T, typename S >
84- Speed wave_speed (T t, S s) // recursive variadic function
79+ template<typename T, typename ...Rest >
80+ struct Wrap <T, Rest ...>
8581{
86- if constexpr (std::is_same_v<T, Permittivity>)
82+
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)
8794 {
88- return wave_speed_inside(t, s );
95+ return first(v );
8996 }
90- else
97+
98+ template<typename F>
99+ requires (!std::is_same_v<T,F>)
100+ decltype(auto) operator()(F v)
91101 {
92- return wave_speed_inside(s, t );
102+ return rest(v );
93103 }
94- }
104+
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)
109+ {
110+ static_assert( (sizeof...(Args) == n) );
111+ return ( operator()(std::forward<Args>(args)) * ... );
112+ }
113+ };
114+
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+ };
95120
96121
97122int main()
98123{
99- constexpr auto vacuum_permittivity = Permittivity(8.85418781762039e-12) ;
100- constexpr auto pi = 3.14159265358979323846 ;
101- constexpr auto vacuum_permeability = Permeability(4 * pi * 1e-7) ;
124+ rho_type rho{1.0} ;
125+ theta_type theta{3.14 / 3.0} ;
126+ phi_type phi{3.14/2.0} ;
102127
103- auto speed_one = wave_speed(vacuum_permittivity, vacuum_permeability);
104- auto speed_two = wave_speed(vacuum_permeability, vacuum_permittivity);
105- // speed_one == speed_two
128+ assert(x_coord(rho,theta,phi) == x_coord(theta,rho,phi));
129+ assert(x_coord(rho,theta,phi) == x_coord(phi,rho,theta));
106130}
107131```
108132
0 commit comments