lambda.hpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. // Boost.Units - A C++ library for zero-overhead dimensional analysis and
  2. // unit/quantity manipulation and conversion
  3. //
  4. // Copyright (C) 2003-2008 Matthias Christian Schabel
  5. // Copyright (C) 2008 Steven Watanabe
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See
  8. // accompanying file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. // $Id: lambda.hpp 27 2008-06-16 14:50:58Z maehne $
  11. #ifndef BOOST_UNITS_LAMBDA_HPP
  12. #define BOOST_UNITS_LAMBDA_HPP
  13. ////////////////////////////////////////////////////////////////////////
  14. ///
  15. /// \file lambda.hpp
  16. ///
  17. /// \brief Definitions to ease the usage of Boost.Units' quantity,
  18. /// unit, and absolute types in functors created with the
  19. /// Boost.Lambda library.
  20. ///
  21. /// \author Torsten Maehne
  22. /// \date 2008-06-16
  23. ///
  24. /// Boost.Lambda's return type deduction system is extented to make
  25. /// use of Boost.Units' typeof_helper trait classes for Boost.Units'
  26. /// quantity, absolute, and unit template classes.
  27. ///
  28. ////////////////////////////////////////////////////////////////////////
  29. #include <boost/lambda/lambda.hpp>
  30. #include <boost/units/units_fwd.hpp>
  31. #include <boost/units/detail/dimensionless_unit.hpp>
  32. #include <boost/units/operators.hpp>
  33. namespace boost {
  34. namespace lambda {
  35. /// Partial specialization of return type trait for action
  36. /// unit<Dim, System> * Y.
  37. template<typename System, typename Dim, typename Y>
  38. struct plain_return_type_2<arithmetic_action<multiply_action>,
  39. boost::units::unit<Dim, System>,
  40. Y > {
  41. typedef typename boost::units::multiply_typeof_helper<
  42. boost::units::unit<Dim, System>, Y >::type type;
  43. };
  44. } // namespace lambda
  45. namespace units {
  46. template<typename System, typename Dim, typename Arg>
  47. struct multiply_typeof_helper<boost::units::unit<Dim, System>, boost::lambda::lambda_functor<Arg> > {
  48. typedef boost::lambda::lambda_functor<
  49. boost::lambda::lambda_functor_base<
  50. boost::lambda::arithmetic_action<boost::lambda::multiply_action>,
  51. tuple<typename boost::lambda::const_copy_argument<const boost::units::unit<Dim, System> >::type, boost::lambda::lambda_functor<Arg> >
  52. >
  53. > type;
  54. };
  55. /// Disambiguating overload for action
  56. /// unit<Dim, System> * lambda_functor<Arg>
  57. /// based on \<boost/lambda/detail/operators.hpp\>.
  58. template<typename System, typename Dim, typename Arg>
  59. inline const typename multiply_typeof_helper<boost::units::unit<Dim, System>, boost::lambda::lambda_functor<Arg> >::type
  60. operator*(const boost::units::unit<Dim, System>& a,
  61. const boost::lambda::lambda_functor<Arg>& b) {
  62. return typename multiply_typeof_helper<boost::units::unit<Dim, System>, boost::lambda::lambda_functor<Arg> >::type::inherited
  63. (tuple<typename boost::lambda::const_copy_argument<const boost::units::unit<Dim, System> >::type,
  64. boost::lambda::lambda_functor<Arg> >
  65. (a, b));
  66. }
  67. } // namespace units
  68. namespace lambda {
  69. /// Partial specialization of return type trait for action
  70. /// unit<Dim, System> / Y.
  71. template<typename System, typename Dim, typename Y>
  72. struct plain_return_type_2<arithmetic_action<divide_action>,
  73. boost::units::unit<Dim, System>,
  74. Y > {
  75. typedef typename boost::units::divide_typeof_helper<
  76. boost::units::unit<Dim, System>, Y >::type type;
  77. };
  78. } // namespace lambda
  79. namespace units {
  80. template<typename System, typename Dim, typename Arg>
  81. struct divide_typeof_helper<boost::units::unit<Dim, System>, boost::lambda::lambda_functor<Arg> > {
  82. typedef boost::lambda::lambda_functor<
  83. boost::lambda::lambda_functor_base<
  84. boost::lambda::arithmetic_action<boost::lambda::divide_action>,
  85. tuple<typename boost::lambda::const_copy_argument<const boost::units::unit<Dim, System> >::type, boost::lambda::lambda_functor<Arg> >
  86. >
  87. > type;
  88. };
  89. /// Disambiguating overload for action
  90. /// unit<Dim, System> / lambda_functor<Arg>
  91. /// based on \<boost/lambda/detail/operators.hpp\>.
  92. template<typename System, typename Dim, typename Arg>
  93. inline const typename divide_typeof_helper<boost::units::unit<Dim, System>, boost::lambda::lambda_functor<Arg> >::type
  94. operator/(const boost::units::unit<Dim, System>& a,
  95. const boost::lambda::lambda_functor<Arg>& b) {
  96. return typename divide_typeof_helper<boost::units::unit<Dim, System>, boost::lambda::lambda_functor<Arg> >::type::inherited
  97. (tuple<typename boost::lambda::const_copy_argument<const boost::units::unit<Dim, System> >::type,
  98. boost::lambda::lambda_functor<Arg> >
  99. (a, b));
  100. }
  101. } // namespace units
  102. namespace lambda {
  103. /// Partial specialization of return type trait for action
  104. /// Y * unit<Dim, System>.
  105. template<typename System, typename Dim, typename Y>
  106. struct plain_return_type_2<arithmetic_action<multiply_action>,
  107. Y,
  108. boost::units::unit<Dim, System> > {
  109. typedef typename boost::units::multiply_typeof_helper<
  110. Y, boost::units::unit<Dim, System> >::type type;
  111. };
  112. } // namespace lambda
  113. namespace units {
  114. template<typename System, typename Dim, typename Arg>
  115. struct multiply_typeof_helper<boost::lambda::lambda_functor<Arg>, boost::units::unit<Dim, System> > {
  116. typedef boost::lambda::lambda_functor<
  117. boost::lambda::lambda_functor_base<
  118. boost::lambda::arithmetic_action<boost::lambda::multiply_action>,
  119. tuple<boost::lambda::lambda_functor<Arg>, typename boost::lambda::const_copy_argument<const boost::units::unit<Dim, System> >::type>
  120. >
  121. > type;
  122. };
  123. /// Disambiguating overload for action
  124. /// lambda_functor<Arg> * unit<Dim, System>
  125. /// based on \<boost/lambda/detail/operators.hpp\>.
  126. template<typename System, typename Dim, typename Arg>
  127. inline const typename multiply_typeof_helper<boost::lambda::lambda_functor<Arg>, boost::units::unit<Dim, System> >::type
  128. operator*(const boost::lambda::lambda_functor<Arg>& a,
  129. const boost::units::unit<Dim, System>& b) {
  130. return typename multiply_typeof_helper<boost::lambda::lambda_functor<Arg>, boost::units::unit<Dim, System> >::type::inherited
  131. (tuple<boost::lambda::lambda_functor<Arg>,
  132. typename boost::lambda::const_copy_argument<const boost::units::unit<Dim, System> >::type>
  133. (a, b));
  134. }
  135. } // namespace units
  136. namespace lambda {
  137. /// Partial specialization of return type trait for action
  138. /// Y / unit<Dim, System>.
  139. template<typename System, typename Dim, typename Y>
  140. struct plain_return_type_2<arithmetic_action<divide_action>,
  141. Y,
  142. boost::units::unit<Dim, System> > {
  143. typedef typename boost::units::divide_typeof_helper<
  144. Y, boost::units::unit<Dim, System> >::type type;
  145. };
  146. } // namespace lambda
  147. namespace units {
  148. template<typename System, typename Dim, typename Arg>
  149. struct divide_typeof_helper<boost::lambda::lambda_functor<Arg>, boost::units::unit<Dim, System> > {
  150. typedef boost::lambda::lambda_functor<
  151. boost::lambda::lambda_functor_base<
  152. boost::lambda::arithmetic_action<boost::lambda::divide_action>,
  153. tuple<boost::lambda::lambda_functor<Arg>, typename boost::lambda::const_copy_argument<const boost::units::unit<Dim, System> >::type>
  154. >
  155. > type;
  156. };
  157. /// Disambiguating overload for action
  158. /// lambda_functor<Arg> / unit<Dim, System>
  159. /// based on \<boost/lambda/detail/operators.hpp\>.
  160. template<typename System, typename Dim, typename Arg>
  161. inline const typename divide_typeof_helper<boost::lambda::lambda_functor<Arg>, boost::units::unit<Dim, System> >::type
  162. operator/(const boost::lambda::lambda_functor<Arg>& a,
  163. const boost::units::unit<Dim, System>& b) {
  164. return typename divide_typeof_helper<boost::lambda::lambda_functor<Arg>, boost::units::unit<Dim, System> >::type::inherited
  165. (tuple<boost::lambda::lambda_functor<Arg>,
  166. typename boost::lambda::const_copy_argument<const boost::units::unit<Dim, System> >::type>
  167. (a, b));
  168. }
  169. } // namespace units
  170. namespace lambda {
  171. /// Partial specialization of return type trait for action
  172. /// quantity<Unit, X> * X.
  173. template<typename Unit, typename X>
  174. struct plain_return_type_2<arithmetic_action<multiply_action>,
  175. boost::units::quantity<Unit, X>,
  176. X> {
  177. typedef typename boost::units::multiply_typeof_helper<
  178. boost::units::quantity<Unit, X>, X>::type type;
  179. };
  180. /// Partial specialization of return type trait for action
  181. /// X * quantity<Unit, X>.
  182. template<typename Unit, typename X>
  183. struct plain_return_type_2<arithmetic_action<multiply_action>,
  184. X,
  185. boost::units::quantity<Unit, X> > {
  186. typedef typename boost::units::multiply_typeof_helper<
  187. X, boost::units::quantity<Unit, X> >::type type;
  188. };
  189. /// Partial specialization of return type trait for action
  190. /// quantity<Unit, X> / X.
  191. template<typename Unit, typename X>
  192. struct plain_return_type_2<arithmetic_action<divide_action>,
  193. boost::units::quantity<Unit, X>,
  194. X> {
  195. typedef typename boost::units::divide_typeof_helper<
  196. boost::units::quantity<Unit, X>, X>::type type;
  197. };
  198. /// Partial specialization of return type trait for action
  199. /// X / quantity<Unit, X>.
  200. template<typename Unit, typename X>
  201. struct plain_return_type_2<arithmetic_action<divide_action>,
  202. X,
  203. boost::units::quantity<Unit, X> > {
  204. typedef typename boost::units::divide_typeof_helper<
  205. X, boost::units::quantity<Unit, X> >::type type;
  206. };
  207. /// Partial specialization of return type trait for action
  208. /// unit<Dim1, System1> * quantity<Unit2, Y>.
  209. template<typename System1, typename Dim1, typename Unit2, typename Y>
  210. struct plain_return_type_2<arithmetic_action<multiply_action>,
  211. boost::units::unit<Dim1, System1>,
  212. boost::units::quantity<Unit2, Y> > {
  213. typedef typename boost::units::multiply_typeof_helper<
  214. boost::units::unit<Dim1, System1>,
  215. boost::units::quantity<Unit2, Y> >::type type;
  216. };
  217. /// Partial specialization of return type trait for action
  218. /// unit<Dim1, System1> / quantity<Unit2, Y>.
  219. template<typename System1, typename Dim1, typename Unit2, typename Y>
  220. struct plain_return_type_2<arithmetic_action<divide_action>,
  221. boost::units::unit<Dim1, System1>,
  222. boost::units::quantity<Unit2, Y> > {
  223. typedef typename boost::units::divide_typeof_helper<
  224. boost::units::unit<Dim1, System1>,
  225. boost::units::quantity<Unit2, Y> >::type type;
  226. };
  227. /// Partial specialization of return type trait for action
  228. /// quantity<Unit1, Y> * unit<Dim2, System2>.
  229. template<typename Unit1, typename Y, typename System2, typename Dim2>
  230. struct plain_return_type_2<arithmetic_action<multiply_action>,
  231. boost::units::quantity<Unit1, Y>,
  232. boost::units::unit<Dim2, System2> > {
  233. typedef typename boost::units::multiply_typeof_helper<
  234. boost::units::quantity<Unit1, Y>,
  235. boost::units::unit<Dim2, System2> >::type type;
  236. };
  237. /// Partial specialization of return type trait for action
  238. /// quantity<Unit1, Y> / unit<Dim2, System2>.
  239. template<typename Unit1, typename Y, typename System2, typename Dim2>
  240. struct plain_return_type_2<arithmetic_action<divide_action>,
  241. boost::units::quantity<Unit1, Y>,
  242. boost::units::unit<Dim2, System2> > {
  243. typedef typename boost::units::divide_typeof_helper<
  244. boost::units::quantity<Unit1, Y>,
  245. boost::units::unit<Dim2, System2> >::type type;
  246. };
  247. /// Partial specialization of return type trait for action
  248. /// +quantity<Unit, Y>.
  249. template<typename Unit, typename Y>
  250. struct plain_return_type_1<unary_arithmetic_action<plus_action>,
  251. boost::units::quantity<Unit, Y> > {
  252. typedef typename boost::units::unary_plus_typeof_helper<
  253. boost::units::quantity<Unit, Y> >::type type;
  254. };
  255. /// Partial specialization of return type trait for action
  256. /// -quantity<Unit, Y>.
  257. template<typename Unit, typename Y>
  258. struct plain_return_type_1<unary_arithmetic_action<minus_action>,
  259. boost::units::quantity<Unit, Y> > {
  260. typedef typename boost::units::unary_minus_typeof_helper<
  261. boost::units::quantity<Unit, Y> >::type type;
  262. };
  263. /// Partial specialization of return type trait for action
  264. /// quantity<Unit1, X> + quantity<Unit2, Y>.
  265. template<typename Unit1, typename X, typename Unit2, typename Y>
  266. struct plain_return_type_2<arithmetic_action<plus_action>,
  267. boost::units::quantity<Unit1, X>,
  268. boost::units::quantity<Unit2, Y> > {
  269. typedef typename boost::units::add_typeof_helper<
  270. boost::units::quantity<Unit1, X>,
  271. boost::units::quantity<Unit2, Y> >::type type;
  272. };
  273. /// Partial specialization of return type trait for action
  274. /// quantity<dimensionless, X> + Y.
  275. template<typename System, typename X, typename Y>
  276. struct plain_return_type_2<arithmetic_action<plus_action>,
  277. boost::units::quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(System), X>,
  278. Y> {
  279. typedef typename boost::units::add_typeof_helper<
  280. boost::units::quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(System), X>,
  281. Y>::type type;
  282. };
  283. /// Partial specialization of return type trait for action
  284. /// X + quantity<dimensionless, Y>.
  285. template<typename System, typename X, typename Y>
  286. struct plain_return_type_2<arithmetic_action<plus_action>,
  287. X,
  288. boost::units::quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(System), Y> > {
  289. typedef typename boost::units::add_typeof_helper<
  290. X,
  291. boost::units::quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(System), Y> >::type type;
  292. };
  293. /// Partial specialization of return type trait for action
  294. /// quantity<Unit1, X> - quantity<Unit2, Y>.
  295. template<typename Unit1, typename X, typename Unit2, typename Y>
  296. struct plain_return_type_2<arithmetic_action<minus_action>,
  297. boost::units::quantity<Unit1, X>,
  298. boost::units::quantity<Unit2, Y> > {
  299. typedef typename boost::units::subtract_typeof_helper<
  300. boost::units::quantity<Unit1, X>,
  301. boost::units::quantity<Unit2, Y> >::type type;
  302. };
  303. /// Partial specialization of return type trait for action
  304. /// quantity<dimensionless, X> - Y.
  305. template<typename System, typename X, typename Y>
  306. struct plain_return_type_2<arithmetic_action<minus_action>,
  307. boost::units::quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(System), X>,
  308. Y> {
  309. typedef typename boost::units::subtract_typeof_helper<
  310. boost::units::quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(System), X>,
  311. Y>::type type;
  312. };
  313. /// Partial specialization of return type trait for action
  314. /// X - quantity<dimensionless, Y>.
  315. template<typename System, typename X, typename Y>
  316. struct plain_return_type_2<arithmetic_action<minus_action>,
  317. X,
  318. boost::units::quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(System), Y> > {
  319. typedef typename boost::units::subtract_typeof_helper<
  320. X,
  321. boost::units::quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(System), Y> >::type type;
  322. };
  323. /// Partial specialization of return type trait for action
  324. /// quantity<Unit1, X> * quantity<Unit2, Y>.
  325. template<typename Unit1, typename X, typename Unit2, typename Y>
  326. struct plain_return_type_2<arithmetic_action<multiply_action>,
  327. boost::units::quantity<Unit1, X>,
  328. boost::units::quantity<Unit2, Y> > {
  329. typedef typename boost::units::multiply_typeof_helper<
  330. boost::units::quantity<Unit1, X>,
  331. boost::units::quantity<Unit2, Y> >::type type;
  332. };
  333. /// Partial specialization of return type trait for action
  334. /// quantity<Unit1, X> / quantity<Unit2, Y>.
  335. template<typename Unit1, typename X, typename Unit2, typename Y>
  336. struct plain_return_type_2<arithmetic_action<divide_action>,
  337. boost::units::quantity<Unit1, X>,
  338. boost::units::quantity<Unit2, Y> > {
  339. typedef typename boost::units::divide_typeof_helper<
  340. boost::units::quantity<Unit1, X>,
  341. boost::units::quantity<Unit2, Y> >::type type;
  342. };
  343. ////////////////////////////////////////////////////////////////////////
  344. // Partial specialization of Boost.Lambda's trait classes for all
  345. // operators overloaded in <boost/units/unit.hpp>
  346. ////////////////////////////////////////////////////////////////////////
  347. /// Partial specialization of return type trait for action
  348. /// +unit<Dim, System>.
  349. template<typename Dim, typename System>
  350. struct plain_return_type_1<unary_arithmetic_action<plus_action>,
  351. boost::units::unit<Dim, System> > {
  352. typedef typename boost::units::unary_plus_typeof_helper<
  353. boost::units::unit<Dim, System> >::type type;
  354. };
  355. /// Partial specialization of return type trait for action
  356. /// -unit<Dim, System>.
  357. template<typename Dim, typename System>
  358. struct plain_return_type_1<unary_arithmetic_action<minus_action>,
  359. boost::units::unit<Dim, System> > {
  360. typedef typename boost::units::unary_minus_typeof_helper<
  361. boost::units::unit<Dim, System> >::type type;
  362. };
  363. /// Partial specialization of return type trait for action
  364. /// unit<Dim1, System1> + unit<Dim2, System2>.
  365. template<typename Dim1, typename Dim2, typename System1, typename System2>
  366. struct plain_return_type_2<arithmetic_action<plus_action>,
  367. boost::units::unit<Dim1, System1>,
  368. boost::units::unit<Dim2, System2> > {
  369. typedef typename boost::units::add_typeof_helper<
  370. boost::units::unit<Dim1, System1>,
  371. boost::units::unit<Dim2, System2> >::type type;
  372. };
  373. /// Partial specialization of return type trait for action
  374. /// unit<Dim1, System1> - unit<Dim2, System2>.
  375. template<typename Dim1, typename Dim2, typename System1, typename System2>
  376. struct plain_return_type_2<arithmetic_action<minus_action>,
  377. boost::units::unit<Dim1, System1>,
  378. boost::units::unit<Dim2, System2> > {
  379. typedef typename boost::units::subtract_typeof_helper<
  380. boost::units::unit<Dim1, System1>,
  381. boost::units::unit<Dim2, System2> >::type type;
  382. };
  383. /// Partial specialization of return type trait for action
  384. /// unit<Dim1, System1> * unit<Dim2, System2>.
  385. template<typename Dim1, typename Dim2, typename System1, typename System2>
  386. struct plain_return_type_2<arithmetic_action<multiply_action>,
  387. boost::units::unit<Dim1, System1>,
  388. boost::units::unit<Dim2, System2> > {
  389. typedef typename boost::units::multiply_typeof_helper<
  390. boost::units::unit<Dim1, System1>,
  391. boost::units::unit<Dim2, System2> >::type type;
  392. };
  393. /// Partial specialization of return type trait for action
  394. /// unit<Dim1, System1> / unit<Dim2, System2>.
  395. template<typename Dim1, typename Dim2, typename System1, typename System2>
  396. struct plain_return_type_2<arithmetic_action<divide_action>,
  397. boost::units::unit<Dim1, System1>,
  398. boost::units::unit<Dim2, System2> > {
  399. typedef typename boost::units::divide_typeof_helper<
  400. boost::units::unit<Dim1, System1>,
  401. boost::units::unit<Dim2, System2> >::type type;
  402. };
  403. ////////////////////////////////////////////////////////////////////////
  404. // Partial specialization of Boost.Lambda's trait classes for all
  405. // operators overloaded in <boost/units/absolute.hpp>
  406. ////////////////////////////////////////////////////////////////////////
  407. /// Partial specialization of return type trait for action
  408. /// absolute<Y> + Y.
  409. template<typename Y>
  410. struct plain_return_type_2<arithmetic_action<plus_action>,
  411. boost::units::absolute<Y>,
  412. Y> {
  413. typedef typename boost::units::absolute<Y> type;
  414. };
  415. /// Partial specialization of return type trait for action
  416. /// Y + absolute<Y>.
  417. template<typename Y>
  418. struct plain_return_type_2<arithmetic_action<plus_action>,
  419. Y,
  420. boost::units::absolute<Y> > {
  421. typedef typename boost::units::absolute<Y> type;
  422. };
  423. /// Partial specialization of return type trait for action
  424. /// absolute<Y> - Y.
  425. template<typename Y>
  426. struct plain_return_type_2<arithmetic_action<minus_action>,
  427. boost::units::absolute<Y>,
  428. Y> {
  429. typedef typename boost::units::absolute<Y> type;
  430. };
  431. /// Partial specialization of return type trait for action
  432. /// absolute<Y> - absolute<Y>.
  433. template<typename Y>
  434. struct plain_return_type_2<arithmetic_action<minus_action>,
  435. boost::units::absolute<Y>,
  436. boost::units::absolute<Y> > {
  437. typedef Y type;
  438. };
  439. /// Partial specialization of return type trait for action
  440. /// T * absolute<unit<D, S> >.
  441. template<typename D, typename S, typename T>
  442. struct plain_return_type_2<arithmetic_action<multiply_action>,
  443. T,
  444. boost::units::absolute<boost::units::unit<D, S> > > {
  445. typedef typename boost::units::quantity<
  446. boost::units::absolute<boost::units::unit<D, S> >, T> type;
  447. };
  448. } // namespace lambda
  449. namespace units {
  450. template<typename System, typename Dim, typename Arg>
  451. struct multiply_typeof_helper<boost::lambda::lambda_functor<Arg>, boost::units::absolute<boost::units::unit<Dim, System> > > {
  452. typedef boost::lambda::lambda_functor<
  453. boost::lambda::lambda_functor_base<
  454. boost::lambda::arithmetic_action<boost::lambda::multiply_action>,
  455. tuple<boost::lambda::lambda_functor<Arg>,
  456. typename boost::lambda::const_copy_argument<const boost::units::absolute<boost::units::unit<Dim, System> > >::type>
  457. >
  458. > type;
  459. };
  460. /// Disambiguating overload for action
  461. /// lambda_functor<Arg> * absolute<unit<Dim, System> >
  462. /// based on \<boost/lambda/detail/operators.hpp\>.
  463. template<typename System, typename Dim, typename Arg>
  464. inline const typename multiply_typeof_helper<boost::lambda::lambda_functor<Arg>, boost::units::absolute<boost::units::unit<Dim, System> > >::type
  465. operator*(const boost::lambda::lambda_functor<Arg>& a,
  466. const boost::units::absolute<boost::units::unit<Dim, System> >& b) {
  467. return typename multiply_typeof_helper<boost::lambda::lambda_functor<Arg>, boost::units::absolute<boost::units::unit<Dim, System> > >::type::inherited
  468. (tuple<boost::lambda::lambda_functor<Arg>,
  469. typename boost::lambda::const_copy_argument<const boost::units::absolute<boost::units::unit<Dim, System> > >::type>
  470. (a, b));
  471. }
  472. } // namespace units
  473. namespace lambda {
  474. /// Partial specialization of return type trait for action
  475. /// absolute<unit<D, S> > * T.
  476. template<typename D, typename S, typename T>
  477. struct plain_return_type_2<arithmetic_action<multiply_action>,
  478. boost::units::absolute<boost::units::unit<D, S> >,
  479. T> {
  480. typedef typename boost::units::quantity<
  481. boost::units::absolute<boost::units::unit<D, S> >, T> type;
  482. };
  483. } // namespace lambda
  484. namespace units {
  485. template<typename System, typename Dim, typename Arg>
  486. struct multiply_typeof_helper<boost::units::absolute<boost::units::unit<Dim, System> >, boost::lambda::lambda_functor<Arg> > {
  487. typedef boost::lambda::lambda_functor<
  488. boost::lambda::lambda_functor_base<
  489. boost::lambda::arithmetic_action<boost::lambda::multiply_action>,
  490. tuple<typename boost::lambda::const_copy_argument<const boost::units::absolute<boost::units::unit<Dim, System> > >::type,
  491. boost::lambda::lambda_functor<Arg> >
  492. >
  493. > type;
  494. };
  495. /// Disambiguating overload for action
  496. /// absolute<unit<Dim, System> > * lambda_functor<Arg>
  497. /// based on \<boost/lambda/detail/operators.hpp\>.
  498. template<typename System, typename Dim, typename Arg>
  499. inline const typename multiply_typeof_helper<boost::units::absolute<boost::units::unit<Dim, System> >, boost::lambda::lambda_functor<Arg> >::type
  500. operator*(const boost::units::absolute<boost::units::unit<Dim, System> >& a,
  501. const boost::lambda::lambda_functor<Arg>& b) {
  502. return typename multiply_typeof_helper<boost::units::absolute<boost::units::unit<Dim, System> >, boost::lambda::lambda_functor<Arg> >::type::inherited
  503. (tuple<typename boost::lambda::const_copy_argument<const boost::units::absolute<boost::units::unit<Dim, System> > >::type,
  504. boost::lambda::lambda_functor<Arg> >
  505. (a, b));
  506. }
  507. } // namespace units
  508. } // namespace boost
  509. #endif // BOOST_UNITS_LAMBDA_HPP