File indexing completed on 2025-01-18 09:53:13
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_UNITS_DIMENSION_IMPL_HPP
0012 #define BOOST_UNITS_DIMENSION_IMPL_HPP
0013
0014 #include <boost/mpl/begin_end.hpp>
0015 #include <boost/mpl/deref.hpp>
0016 #include <boost/mpl/if.hpp>
0017 #include <boost/mpl/list.hpp>
0018 #include <boost/mpl/next.hpp>
0019 #include <boost/mpl/size.hpp>
0020 #include <boost/mpl/less.hpp>
0021
0022 #include <boost/units/config.hpp>
0023 #include <boost/units/dimensionless_type.hpp>
0024 #include <boost/units/static_rational.hpp>
0025 #include <boost/units/units_fwd.hpp>
0026 #include <boost/units/detail/dimension_list.hpp>
0027 #include <boost/units/detail/push_front_if.hpp>
0028 #include <boost/units/detail/push_front_or_add.hpp>
0029
0030
0031
0032
0033 namespace boost {
0034
0035 namespace units {
0036
0037 namespace detail {
0038
0039 template<int N>
0040 struct insertion_sort_dims_insert;
0041
0042 template<bool is_greater>
0043 struct insertion_sort_dims_comparison_impl;
0044
0045
0046 template<>
0047 struct insertion_sort_dims_comparison_impl<true> {
0048 template<class Begin, int N, class T>
0049 struct apply {
0050 typedef list<
0051 typename Begin::item,
0052 typename insertion_sort_dims_insert<N - 1>::template apply<
0053 typename Begin::next,
0054 T
0055 >::type
0056 > type;
0057 };
0058 };
0059
0060
0061
0062 template<>
0063 struct insertion_sort_dims_comparison_impl<false> {
0064 template<class Begin, int N, class T>
0065 struct apply {
0066 typedef typename push_front_or_add<Begin, T>::type type;
0067 };
0068 };
0069
0070 template<int N>
0071 struct insertion_sort_dims_insert {
0072 template<class Begin, class T>
0073 struct apply {
0074 typedef typename insertion_sort_dims_comparison_impl<mpl::less<typename Begin::item, T>::value>::template apply<
0075 Begin,
0076 N,
0077 T
0078 >::type type;
0079 };
0080 };
0081
0082 template<>
0083 struct insertion_sort_dims_insert<0> {
0084 template<class Begin, class T>
0085 struct apply {
0086 typedef list<T, dimensionless_type> type;
0087 };
0088 };
0089
0090 template<int N>
0091 struct insertion_sort_dims_mpl_sequence {
0092 template<class Begin>
0093 struct apply {
0094 typedef typename insertion_sort_dims_mpl_sequence<N - 1>::template apply<typename mpl::next<Begin>::type>::type next;
0095 typedef typename insertion_sort_dims_insert<(next::size::value)>::template apply<next, typename mpl::deref<Begin>::type>::type type;
0096 };
0097 };
0098
0099 template<>
0100 struct insertion_sort_dims_mpl_sequence<0> {
0101 template<class Begin>
0102 struct apply {
0103 typedef dimensionless_type type;
0104 };
0105 };
0106
0107 template<int N>
0108 struct insertion_sort_dims_impl {
0109 template<class Begin>
0110 struct apply {
0111 typedef typename insertion_sort_dims_impl<N - 1>::template apply<typename Begin::next>::type next;
0112 typedef typename insertion_sort_dims_insert<(next::size::value)>::template apply<next, typename Begin::item>::type type;
0113 };
0114 };
0115
0116 template<>
0117 struct insertion_sort_dims_impl<0> {
0118 template<class Begin>
0119 struct apply {
0120 typedef dimensionless_type type;
0121 };
0122 };
0123
0124 template<class T>
0125 struct sort_dims
0126 {
0127 typedef typename insertion_sort_dims_mpl_sequence<mpl::size<T>::value>::template apply<typename mpl::begin<T>::type>::type type;
0128 };
0129
0130
0131 template<class T, class Next>
0132 struct sort_dims<list<T, Next> >
0133 {
0134 typedef typename insertion_sort_dims_impl<list<T, Next>::size::value>::template apply<list<T, Next> >::type type;
0135 };
0136
0137
0138 template<bool less, bool greater>
0139 struct merge_dimensions_func;
0140
0141 template<int N1, int N2>
0142 struct merge_dimensions_impl;
0143
0144 template<>
0145 struct merge_dimensions_func<true, false>
0146 {
0147 template<typename Begin1, typename Begin2, int N1, int N2>
0148 struct apply
0149 {
0150 typedef list<
0151 typename Begin1::item,
0152 typename merge_dimensions_impl<N1 - 1, N2>::template apply<
0153 typename Begin1::next,
0154 Begin2
0155 >::type
0156 > type;
0157 };
0158 };
0159
0160 template<>
0161 struct merge_dimensions_func<false, true> {
0162 template<typename Begin1, typename Begin2, int N1, int N2>
0163 struct apply
0164 {
0165 typedef list<
0166 typename Begin2::item,
0167 typename merge_dimensions_impl<N2 - 1, N1>::template apply<
0168 typename Begin2::next,
0169 Begin1
0170 >::type
0171 > type;
0172 };
0173 };
0174
0175 template<>
0176 struct merge_dimensions_func<false, false> {
0177 template<typename Begin1, typename Begin2, int N1, int N2>
0178 struct apply
0179 {
0180 typedef typename mpl::plus<typename Begin1::item, typename Begin2::item>::type combined;
0181 typedef typename push_front_if<!is_empty_dim<combined>::value>::template apply<
0182 typename merge_dimensions_impl<N1 - 1, N2 - 1>::template apply<
0183 typename Begin1::next,
0184 typename Begin2::next
0185 >::type,
0186 combined
0187 >::type type;
0188 };
0189 };
0190
0191 template<int N1, int N2>
0192 struct merge_dimensions_impl {
0193 template<typename Begin1, typename Begin2>
0194 struct apply
0195 {
0196 typedef typename Begin1::item dim1;
0197 typedef typename Begin2::item dim2;
0198
0199 typedef typename merge_dimensions_func<(mpl::less<dim1,dim2>::value == true),
0200 (mpl::less<dim2,dim1>::value == true)>::template apply<
0201 Begin1,
0202 Begin2,
0203 N1,
0204 N2
0205 >::type type;
0206 };
0207 };
0208
0209 template<typename Sequence1, typename Sequence2>
0210 struct merge_dimensions
0211 {
0212 typedef typename detail::merge_dimensions_impl<Sequence1::size::value,
0213 Sequence2::size::value>::template
0214 apply<
0215 Sequence1,
0216 Sequence2
0217 >::type type;
0218 };
0219
0220 template<int N>
0221 struct iterator_to_list
0222 {
0223 template<typename Begin>
0224 struct apply
0225 {
0226 typedef list<
0227 typename Begin::item,
0228 typename iterator_to_list<N - 1>::template apply<
0229 typename Begin::next
0230 >::type
0231 > type;
0232 };
0233 };
0234
0235 template<>
0236 struct iterator_to_list<0>
0237 {
0238 template<typename Begin>
0239 struct apply {
0240 typedef dimensionless_type type;
0241 };
0242 };
0243
0244 template<int N>
0245 struct merge_dimensions_impl<N, 0>
0246 {
0247 template<typename Begin1, typename Begin2>
0248 struct apply
0249 {
0250 typedef typename iterator_to_list<N>::template apply<Begin1>::type type;
0251 };
0252 };
0253
0254 template<int N>
0255 struct merge_dimensions_impl<0, N>
0256 {
0257 template<typename Begin1, typename Begin2>
0258 struct apply
0259 {
0260 typedef typename iterator_to_list<N>::template apply<Begin2>::type type;
0261 };
0262 };
0263
0264 template<>
0265 struct merge_dimensions_impl<0, 0>
0266 {
0267 template<typename Begin1, typename Begin2>
0268 struct apply
0269 {
0270 typedef dimensionless_type type;
0271 };
0272 };
0273
0274 template<int N>
0275 struct static_inverse_impl
0276 {
0277 template<typename Begin>
0278 struct apply {
0279 typedef list<
0280 typename mpl::negate<typename Begin::item>::type,
0281 typename static_inverse_impl<N - 1>::template apply<
0282 typename Begin::next
0283 >::type
0284 > type;
0285 };
0286 };
0287
0288 template<>
0289 struct static_inverse_impl<0>
0290 {
0291 template<typename Begin>
0292 struct apply
0293 {
0294 typedef dimensionless_type type;
0295 };
0296 };
0297
0298 template<int N>
0299 struct static_power_impl
0300 {
0301 template<typename Begin, typename Ex>
0302 struct apply
0303 {
0304 typedef list<
0305 typename mpl::times<typename Begin::item, Ex>::type,
0306 typename detail::static_power_impl<N - 1>::template apply<typename Begin::next, Ex>::type
0307 > type;
0308 };
0309 };
0310
0311 template<>
0312 struct static_power_impl<0>
0313 {
0314 template<typename Begin, typename Ex>
0315 struct apply
0316 {
0317 typedef dimensionless_type type;
0318 };
0319 };
0320
0321 template<int N>
0322 struct static_root_impl {
0323 template<class Begin, class Ex>
0324 struct apply {
0325 typedef list<
0326 typename mpl::divides<typename Begin::item, Ex>::type,
0327 typename detail::static_root_impl<N - 1>::template apply<typename Begin::next, Ex>::type
0328 > type;
0329 };
0330 };
0331
0332 template<>
0333 struct static_root_impl<0> {
0334 template<class Begin, class Ex>
0335 struct apply
0336 {
0337 typedef dimensionless_type type;
0338 };
0339 };
0340
0341 }
0342
0343 }
0344
0345 }
0346
0347 #endif