@@ -41,19 +41,26 @@ int main()
4141
4242```
4343
44+ You can create boxed types in the following way:
45+ ``` c++
46+ using boxed_type = boxed::boxed<int >;
47+
48+ struct Tag {};
49+ using boxed_type_with_custom_tag = boxed::boxed<int ,Tag>;
50+ ```
4451
45- When you need to get value from boxed type, you need to unbox it
52+ When you need to get value from a boxed type, you need to ` unbox ` it, use ` get ` method, or cast it into another type with ` as ` .
4653``` c++
4754// unbox in declared type. double in this case
48- auto speed_value_native = unbox(speed_of_light);
55+ auto speed_value_native = unbox(speed_of_light); // identical to speed_of_light.get();
4956// unbox into float type
50- auto speed_value_float = unbox<float >(speed_of_light);
57+ auto speed_value_float = unbox<float >(speed_of_light); // identical to speed_of_light.as<float>();
5158// unbox into int type
52- auto speed_value_int = unbox<int >(speed_of_light);
59+ auto speed_value_int = unbox<int >(speed_of_light); // identical to speed_of_light.as<int>();
5360```
5461
5562
56- You can also evaluate expressions with boxed types without the need of unboxing them if explicitly declare the resulted type
63+ You can also evaluate expressions with boxed types without the need of unboxing them
5764``` c++
5865auto speed_of_light = Speed(299792458.0 );
5966auto value = speed_of_light * 2.0 ; // type of value is Speed
@@ -63,50 +70,90 @@ double value_d = speed_of_light * 2.0;
6370```
6471
6572
66- # More examples of usage
67- You can crate functions that will automatically adjust order of parameters. Complete code see: [ godbolt] ( https://godbolt.org/z/aqobbcGe6 )
73+ # Another examples
74+ You can create functions that will automatically adjust order of parameters. [ godbolt] ( https://godbolt.org/z/n8Ez5K6vq )
6875
6976``` c++
7077using rho_type = boxed::boxed<double >;
7178using theta_type = boxed::boxed<double >;
7279using phi_type = boxed::boxed<double >;
7380
74- template <typename ... F>
75- struct overload : F...{ using F::operator()...;};
81+ template <typename ... F> struct overload : F... {
82+ using F::operator()...;
83+ };
7684
77- template<typename... Ts> overload(Ts...) -> overload<Ts...>;
85+ template <typename... Ts> overload(Ts...) -> overload<Ts...>;
7886
79- template<typename... Ts>
80- struct Wrap
81- {
82- overload<Ts...> func_wrap;
87+ template <typename... Ts> struct Wrap {
88+ overload<Ts...> func_wrap;
8389
84- Wrap (Ts... funcs): func_wrap(funcs...){}
90+ Wrap(Ts... funcs) : func_wrap(funcs...) {}
8591
86- template<typename... Args>
87- auto operator()(Args... args)
88- {
89- return (func_wrap(args)*...);
90- }
92+ template <typename... Args> auto operator()(Args... args) {
93+ return (func_wrap(args) * ...);
94+ }
9195};
9296
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- );
97+ auto x_coord = Wrap([ ] (rho_type rho) { return unbox(rho); },
98+ [ ] (theta_type theta) { return sin(unbox(theta)); },
99+ [ ] (phi_type phi) { return cos(unbox(phi)); });
97100
98- int main()
99- {
100- rho_type rho{1.0};
101- theta_type theta{3.14 / 3.0};
102- phi_type phi{3.14/2.0};
101+ int main() {
102+ rho_type rho{1.0};
103+ theta_type theta{3.14 / 3.0};
104+ phi_type phi{3.14 / 2.0};
103105
104- std::cout << x_coord(rho,theta,phi) << std::endl; // 0.000689428
105- std::cout << x_coord(phi,theta,rho) << std::endl; // 0.000689428
106- std::cout << x_coord(rho,phi,theta) << std::endl; // 0.000689428
106+ std::cout << x_coord(rho, theta, phi) << std::endl;
107+ std::cout << x_coord(phi, theta, rho) << std::endl;
108+ std::cout << x_coord(rho, phi, theta) << std::endl;
107109}
108110```
109111
112+ Or using another approach: [godbolt](https://godbolt.org/z/fjhaaT5hh)
113+
114+ ``` c++
115+ using rho_type = boxed::boxed<double>;
116+ using theta_type = boxed::boxed<double>;
117+ using phi_type = boxed::boxed<double>;
118+
119+ template <typename Func, typename... Tuple> struct Wrap_with_tuple {
120+ using type_order = std::tuple<Tuple...>;
121+
122+ Wrap_with_tuple(Func f, type_order s) : _func(f), _order(s) {};
123+
124+ template <typename... F> decltype(auto) operator()(F... args) {
125+ auto arg_tuple = std::make_tuple(args...);
126+ auto ints = std::make_index_sequence<sizeof...(args)>{};
127+ return make_call(arg_tuple, ints);
128+ }
129+
130+ template <typename call_tuple, typename T, T... ints>
131+ decltype(auto) make_call(call_tuple arg_tuple,
132+ std::integer_sequence<T, ints...> int_seq) {
133+ return _func(
134+ std::get<std::decay_t<decltype(std::get<ints>(_order))>>(arg_tuple)...);
135+ }
136+
137+ Func _func;
138+ type_order _order;
139+ };
140+
141+ auto x_coord = Wrap_with_tuple(
142+ [](rho_type rho, theta_type theta, phi_type phi) {
143+ return unbox(rho) * sin(unbox(theta)) * cos(unbox(phi));
144+ },
145+ std::make_tuple(rho_type{}, theta_type{}, phi_type{}));
146+
147+ int main() {
148+ rho_type rho{1.0};
149+ theta_type theta{3.14 / 3.0};
150+ phi_type phi{3.14 / 2.0};
151+
152+ std::cout << x_coord(rho, theta, phi) << std::endl;
153+ std::cout << x_coord(phi, theta, rho) << std::endl;
154+ std::cout << x_coord(rho, phi, theta) << std::endl;
155+ }
156+ ```
110157
111158
112159### License
0 commit comments