@@ -41,19 +41,26 @@ int main()
41
41
42
42
```
43
43
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
+ ```
44
51
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 ` .
46
53
``` c++
47
54
// 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();
49
56
// 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>();
51
58
// 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>();
53
60
```
54
61
55
62
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
57
64
``` c++
58
65
auto speed_of_light = Speed(299792458.0 );
59
66
auto value = speed_of_light * 2.0 ; // type of value is Speed
@@ -63,50 +70,90 @@ double value_d = speed_of_light * 2.0;
63
70
```
64
71
65
72
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 )
68
75
69
76
``` c++
70
77
using rho_type = boxed::boxed<double >;
71
78
using theta_type = boxed::boxed<double >;
72
79
using phi_type = boxed::boxed<double >;
73
80
74
- template <typename ... F>
75
- struct overload : F...{ using F::operator()...;};
81
+ template <typename ... F> struct overload : F... {
82
+ using F::operator()...;
83
+ };
76
84
77
- template<typename... Ts> overload(Ts...) -> overload<Ts...>;
85
+ template <typename... Ts> overload(Ts...) -> overload<Ts...>;
78
86
79
- template<typename... Ts>
80
- struct Wrap
81
- {
82
- overload<Ts...> func_wrap;
87
+ template <typename... Ts> struct Wrap {
88
+ overload<Ts...> func_wrap;
83
89
84
- Wrap (Ts... funcs): func_wrap(funcs...){}
90
+ Wrap(Ts... funcs) : func_wrap(funcs...) {}
85
91
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
+ }
91
95
};
92
96
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)); });
97
100
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};
103
105
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;
107
109
}
108
110
```
109
111
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
+ ```
110
157
111
158
112
159
### License
0 commit comments