et_ops.hpp 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright 2011 John Maddock. Distributed under the Boost
  3. // Software License, Version 1.0. (See accompanying file
  4. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef BOOST_MP_ET_OPS_HPP
  6. #define BOOST_MP_ET_OPS_HPP
  7. namespace boost{ namespace multiprecision{
  8. //
  9. // Non-member operators for number:
  10. //
  11. // Unary operators first.
  12. // Note that these *must* return by value, even though that's somewhat against
  13. // existing practice. The issue is that in C++11 land one could easily and legitimately
  14. // write:
  15. // auto x = +1234_my_user_defined_suffix;
  16. // which would result in a dangling-reference-to-temporary if unary + returned a reference
  17. // to it's argument. While return-by-value is obviously inefficient in other situations
  18. // the reality is that no one ever uses unary operator+ anyway...!
  19. //
  20. template <class B, expression_template_option ExpressionTemplates>
  21. inline BOOST_CONSTEXPR const number<B, ExpressionTemplates> operator + (const number<B, ExpressionTemplates>& v) { return v; }
  22. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  23. inline BOOST_CONSTEXPR const detail::expression<tag, Arg1, Arg2, Arg3, Arg4> operator + (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& v) { return v; }
  24. template <class B>
  25. inline detail::expression<detail::negate, number<B, et_on> > operator - (const number<B, et_on>& v)
  26. {
  27. BOOST_STATIC_ASSERT_MSG(is_signed_number<B>::value, "Negating an unsigned type results in ill-defined behavior.");
  28. return detail::expression<detail::negate, number<B, et_on> >(v);
  29. }
  30. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  31. inline detail::expression<detail::negate, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > operator - (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& v)
  32. {
  33. BOOST_STATIC_ASSERT_MSG((is_signed_number<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value), "Negating an unsigned type results in ill-defined behavior.");
  34. return detail::expression<detail::negate, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(v);
  35. }
  36. template <class B>
  37. inline typename enable_if_c<number_category<B>::value == number_kind_integer,
  38. detail::expression<detail::complement_immediates, number<B, et_on> > >::type
  39. operator ~ (const number<B, et_on>& v) { return detail::expression<detail::complement_immediates, number<B, et_on> >(v); }
  40. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  41. inline typename enable_if_c<number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer,
  42. detail::expression<detail::bitwise_complement, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
  43. operator ~ (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& v) { return detail::expression<detail::bitwise_complement, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(v); }
  44. //
  45. // Then addition:
  46. //
  47. template <class B>
  48. inline detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >
  49. operator + (const number<B, et_on>& a, const number<B, et_on>& b)
  50. {
  51. return detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >(a, b);
  52. }
  53. template <class B, class V>
  54. inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::add_immediates, number<B, et_on>, V > >::type
  55. operator + (const number<B, et_on>& a, const V& b)
  56. {
  57. return detail::expression<detail::add_immediates, number<B, et_on>, V >(a, b);
  58. }
  59. template <class V, class B>
  60. inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::add_immediates, V, number<B, et_on> > >::type
  61. operator + (const V& a, const number<B, et_on>& b)
  62. {
  63. return detail::expression<detail::add_immediates, V, number<B, et_on> >(a, b);
  64. }
  65. template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  66. inline detail::expression<detail::plus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >
  67. operator + (const number<B, ET>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
  68. {
  69. return detail::expression<detail::plus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
  70. }
  71. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
  72. inline detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >
  73. operator + (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
  74. {
  75. return detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b);
  76. }
  77. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
  78. inline detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >
  79. operator + (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
  80. {
  81. return detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
  82. }
  83. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
  84. inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>, detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V > >::type
  85. operator + (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
  86. {
  87. return detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b);
  88. }
  89. template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  90. inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>, detail::expression<detail::plus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
  91. operator + (const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
  92. {
  93. return detail::expression<detail::plus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
  94. }
  95. //
  96. // Fused multiply add:
  97. //
  98. template <class V, class Arg1, class Arg2, class Arg3, class Arg4>
  99. inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>,
  100. detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V> >::type
  101. operator + (const V& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b)
  102. {
  103. return detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V>(b.left(), b.right(), a);
  104. }
  105. template <class Arg1, class Arg2, class Arg3, class Arg4, class V>
  106. inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>,
  107. detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V> >::type
  108. operator + (const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
  109. {
  110. return detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V>(a.left(), a.right(), b);
  111. }
  112. template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
  113. inline detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> >
  114. operator + (const number<B, ET>& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b)
  115. {
  116. return detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> >(b.left(), b.right(), a);
  117. }
  118. template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
  119. inline detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> >
  120. operator + (const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
  121. {
  122. return detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> >(a.left(), a.right(), b);
  123. }
  124. //
  125. // Fused multiply subtract:
  126. //
  127. template <class V, class Arg1, class Arg2, class Arg3, class Arg4>
  128. inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>,
  129. detail::expression<detail::negate, detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V> > >::type
  130. operator - (const V& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b)
  131. {
  132. return detail::expression<detail::negate, detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V> >
  133. (detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V>(b.left(), b.right(), a));
  134. }
  135. template <class Arg1, class Arg2, class Arg3, class Arg4, class V>
  136. inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>,
  137. detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V> >::type
  138. operator - (const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
  139. {
  140. return detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V>(a.left(), a.right(), b);
  141. }
  142. template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
  143. inline detail::expression<detail::negate, detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> > >
  144. operator - (const number<B, ET>& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b)
  145. {
  146. return detail::expression<detail::negate, detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> > >
  147. (detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> >(b.left(), b.right(), a));
  148. }
  149. template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
  150. inline detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> >
  151. operator - (const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
  152. {
  153. return detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> >(a.left(), a.right(), b);
  154. }
  155. //
  156. // Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries:
  157. //
  158. template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
  159. inline detail::expression<detail::minus, number<B, ET>, Arg1>
  160. operator + (const number<B, ET>& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b)
  161. {
  162. return detail::expression<detail::minus, number<B, ET>, Arg1>(a, b.left_ref());
  163. }
  164. template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
  165. inline detail::expression<detail::minus, number<B, ET>, Arg1>
  166. operator + (const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
  167. {
  168. return detail::expression<detail::minus, number<B, ET>, Arg1>(b, a.left_ref());
  169. }
  170. template <class B>
  171. inline detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >
  172. operator + (const number<B, et_on>& a, const detail::expression<detail::negate, number<B, et_on> >& b)
  173. {
  174. return detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >(a, b.left_ref());
  175. }
  176. template <class B>
  177. inline detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >
  178. operator + (const detail::expression<detail::negate, number<B, et_on> >& a, const number<B, et_on>& b)
  179. {
  180. return detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >(b, a.left_ref());
  181. }
  182. template <class B, class V>
  183. inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::subtract_immediates, V, number<B, et_on> > >::type
  184. operator + (const detail::expression<detail::negate, number<B, et_on> >& a, const V& b)
  185. {
  186. return detail::expression<detail::subtract_immediates, V, number<B, et_on> >(b, a.left_ref());
  187. }
  188. template <class B, class B2, expression_template_option ET>
  189. inline typename enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >, detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> > >::type
  190. operator + (const detail::expression<detail::negate, number<B, et_on> >& a, const number<B2, ET>& b)
  191. {
  192. return detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> >(b, a.left_ref());
  193. }
  194. template <class B2, expression_template_option ET, class B>
  195. inline typename enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >, detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> > >::type
  196. operator + (const number<B2, ET>& a, const detail::expression<detail::negate, number<B, et_on> >& b)
  197. {
  198. return detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> >(a, b.left_ref());
  199. }
  200. template <class B>
  201. inline detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > >
  202. operator + (const detail::expression<detail::negate, number<B, et_on> >& a, const detail::expression<detail::negate, number<B, et_on> >& b)
  203. {
  204. return detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > >(detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >(a.left_ref(), b.left_ref()));
  205. }
  206. //
  207. // Subtraction:
  208. //
  209. template <class B>
  210. inline detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >
  211. operator - (const number<B, et_on>& a, const number<B, et_on>& b)
  212. {
  213. return detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >(a, b);
  214. }
  215. template <class B, class V>
  216. inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::subtract_immediates, number<B, et_on>, V > >::type
  217. operator - (const number<B, et_on>& a, const V& b)
  218. {
  219. return detail::expression<detail::subtract_immediates, number<B, et_on>, V >(a, b);
  220. }
  221. template <class V, class B>
  222. inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::subtract_immediates, V, number<B, et_on> > >::type
  223. operator - (const V& a, const number<B, et_on>& b)
  224. {
  225. return detail::expression<detail::subtract_immediates, V, number<B, et_on> >(a, b);
  226. }
  227. template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  228. inline detail::expression<detail::minus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >
  229. operator - (const number<B, ET>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
  230. {
  231. return detail::expression<detail::minus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
  232. }
  233. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
  234. inline detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >
  235. operator - (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
  236. {
  237. return detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b);
  238. }
  239. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
  240. inline detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >
  241. operator - (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
  242. {
  243. return detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
  244. }
  245. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
  246. inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>, detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V > >::type
  247. operator - (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
  248. {
  249. return detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b);
  250. }
  251. template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  252. inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>, detail::expression<detail::minus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
  253. operator - (const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
  254. {
  255. return detail::expression<detail::minus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
  256. }
  257. //
  258. // Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries:
  259. //
  260. template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
  261. inline detail::expression<detail::plus, number<B, ET>, Arg1>
  262. operator - (const number<B, ET>& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b)
  263. {
  264. return detail::expression<detail::plus, number<B, ET>, Arg1>(a, b.left_ref());
  265. }
  266. template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
  267. inline detail::expression<detail::negate, detail::expression<detail::plus, number<B, ET>, Arg1> >
  268. operator - (const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
  269. {
  270. return detail::expression<detail::negate, detail::expression<detail::plus, number<B, ET>, Arg1> >(
  271. detail::expression<detail::plus, number<B, ET>, Arg1>(b, a.left_ref()));
  272. }
  273. template <class B>
  274. inline detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >
  275. operator - (const number<B, et_on>& a, const detail::expression<detail::negate, number<B, et_on> >& b)
  276. {
  277. return detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >(a, b.left_ref());
  278. }
  279. template <class B>
  280. inline detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > >
  281. operator - (const detail::expression<detail::negate, number<B, et_on> >& a, const number<B, et_on>& b)
  282. {
  283. return detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > >(
  284. detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >(b, a.left_ref()));
  285. }
  286. template <class B, class V>
  287. inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, V > > >::type
  288. operator - (const detail::expression<detail::negate, number<B, et_on> >& a, const V& b)
  289. {
  290. return detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, V > >(detail::expression<detail::add_immediates, number<B, et_on>, V >(a.left_ref(), b));
  291. }
  292. template <class B, class B2, expression_template_option ET>
  293. inline typename enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >, detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B2, ET> > > >::type
  294. operator - (const detail::expression<detail::negate, number<B, et_on> >& a, const number<B2, ET>& b)
  295. {
  296. return detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B2, ET> > >(detail::expression<detail::add_immediates, number<B, et_on>, number<B2, ET> >(a.left_ref(), b));
  297. }
  298. template <class V, class B>
  299. inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::add_immediates, V, number<B, et_on> > >::type
  300. operator - (const V& a, const detail::expression<detail::negate, number<B, et_on> >& b)
  301. {
  302. return detail::expression<detail::add_immediates, V, number<B, et_on> >(a, b.left_ref());
  303. }
  304. template <class B2, expression_template_option ET, class B>
  305. inline typename enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >, detail::expression<detail::add_immediates, number<B2, ET>, number<B, et_on> > >::type
  306. operator - (const number<B2, ET>& a, const detail::expression<detail::negate, number<B, et_on> >& b)
  307. {
  308. return detail::expression<detail::add_immediates, number<B2, ET>, number<B, et_on> >(a, b.left_ref());
  309. }
  310. //
  311. // Multiplication:
  312. //
  313. template <class B>
  314. inline detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> >
  315. operator * (const number<B, et_on>& a, const number<B, et_on>& b)
  316. {
  317. return detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> >(a, b);
  318. }
  319. template <class B, class V>
  320. inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::multiply_immediates, number<B, et_on>, V > >::type
  321. operator * (const number<B, et_on>& a, const V& b)
  322. {
  323. return detail::expression<detail::multiply_immediates, number<B, et_on>, V >(a, b);
  324. }
  325. template <class V, class B>
  326. inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::multiply_immediates, V, number<B, et_on> > >::type
  327. operator * (const V& a, const number<B, et_on>& b)
  328. {
  329. return detail::expression<detail::multiply_immediates, V, number<B, et_on> >(a, b);
  330. }
  331. template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  332. inline detail::expression<detail::multiplies, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >
  333. operator * (const number<B, ET>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
  334. {
  335. return detail::expression<detail::multiplies, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
  336. }
  337. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
  338. inline detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >
  339. operator * (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
  340. {
  341. return detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b);
  342. }
  343. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
  344. inline detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >
  345. operator * (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
  346. {
  347. return detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
  348. }
  349. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
  350. inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>, detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V > >::type
  351. operator * (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
  352. {
  353. return detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b);
  354. }
  355. template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  356. inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>, detail::expression<detail::multiplies, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
  357. operator * (const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
  358. {
  359. return detail::expression<detail::multiplies, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
  360. }
  361. //
  362. // Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries:
  363. //
  364. template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
  365. inline detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> >
  366. operator * (const number<B, ET>& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b)
  367. {
  368. return detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> >(
  369. detail::expression<detail::multiplies, number<B, ET>, Arg1> (a, b.left_ref()));
  370. }
  371. template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
  372. inline detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> >
  373. operator * (const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
  374. {
  375. return detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> >(
  376. detail::expression<detail::multiplies, number<B, ET>, Arg1>(b, a.left_ref()));
  377. }
  378. template <class B>
  379. inline detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >
  380. operator * (const number<B, et_on>& a, const detail::expression<detail::negate, number<B, et_on> >& b)
  381. {
  382. return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >(
  383. detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> >(a, b.left_ref()));
  384. }
  385. template <class B>
  386. inline detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >
  387. operator * (const detail::expression<detail::negate, number<B, et_on> >& a, const number<B, et_on>& b)
  388. {
  389. return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >(
  390. detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> >(b, a.left_ref()));
  391. }
  392. template <class B, class V>
  393. inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, V > > >::type
  394. operator * (const detail::expression<detail::negate, number<B, et_on> >& a, const V& b)
  395. {
  396. return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, V > > (
  397. detail::expression<detail::multiply_immediates, number<B, et_on>, V >(a.left_ref(), b));
  398. }
  399. template <class B, class B2, expression_template_option ET>
  400. inline typename enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >, detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > > >::type
  401. operator * (const detail::expression<detail::negate, number<B, et_on> >& a, const number<B2, ET>& b)
  402. {
  403. return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > > (
  404. detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> >(a.left_ref(), b));
  405. }
  406. template <class V, class B>
  407. inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, V > > >::type
  408. operator * (const V& a, const detail::expression<detail::negate, number<B, et_on> >& b)
  409. {
  410. return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, V > >(
  411. detail::expression<detail::multiply_immediates, number<B, et_on>, V >(b.left_ref(), a));
  412. }
  413. template <class B2, expression_template_option ET, class B>
  414. inline typename enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >, detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > > >::type
  415. operator * (const number<B2, ET>& a, const detail::expression<detail::negate, number<B, et_on> >& b)
  416. {
  417. return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > >(
  418. detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> >(b.left_ref(), a));
  419. }
  420. //
  421. // Division:
  422. //
  423. template <class B>
  424. inline detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> >
  425. operator / (const number<B, et_on>& a, const number<B, et_on>& b)
  426. {
  427. return detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> >(a, b);
  428. }
  429. template <class B, class V>
  430. inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::divide_immediates, number<B, et_on>, V > >::type
  431. operator / (const number<B, et_on>& a, const V& b)
  432. {
  433. return detail::expression<detail::divide_immediates, number<B, et_on>, V >(a, b);
  434. }
  435. template <class V, class B>
  436. inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::divide_immediates, V, number<B, et_on> > >::type
  437. operator / (const V& a, const number<B, et_on>& b)
  438. {
  439. return detail::expression<detail::divide_immediates, V, number<B, et_on> >(a, b);
  440. }
  441. template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  442. inline detail::expression<detail::divides, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >
  443. operator / (const number<B, ET>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
  444. {
  445. return detail::expression<detail::divides, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
  446. }
  447. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
  448. inline detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >
  449. operator / (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
  450. {
  451. return detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b);
  452. }
  453. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
  454. inline detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >
  455. operator / (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
  456. {
  457. return detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
  458. }
  459. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
  460. inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>, detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V > >::type
  461. operator / (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
  462. {
  463. return detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b);
  464. }
  465. template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  466. inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>, detail::expression<detail::divides, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
  467. operator / (const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
  468. {
  469. return detail::expression<detail::divides, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
  470. }
  471. //
  472. // Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries:
  473. //
  474. template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4>
  475. inline detail::expression<detail::negate, detail::expression<detail::divides, number<B, ET>, Arg1> >
  476. operator / (const number<B, ET>& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b)
  477. {
  478. return detail::expression<detail::negate, detail::expression<detail::divides, number<B, ET>, Arg1> >(
  479. detail::expression<detail::divides, number<B, ET>, Arg1>(a, b.left_ref()));
  480. }
  481. template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET>
  482. inline detail::expression<detail::negate, detail::expression<detail::divides, Arg1, number<B, ET> > >
  483. operator / (const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b)
  484. {
  485. return detail::expression<detail::negate, detail::expression<detail::divides, Arg1, number<B, ET> > >(
  486. detail::expression<detail::divides, Arg1, number<B, ET> >(a.left_ref(), b));
  487. }
  488. template <class B>
  489. inline detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> > >
  490. operator / (const number<B, et_on>& a, const detail::expression<detail::negate, number<B, et_on> >& b)
  491. {
  492. return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> > >(
  493. detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> >(a, b.left_ref()));
  494. }
  495. template <class B>
  496. inline detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> > >
  497. operator / (const detail::expression<detail::negate, number<B, et_on> >& a, const number<B, et_on>& b)
  498. {
  499. return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> > >(
  500. detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> >(a.left_ref(), b));
  501. }
  502. template <class B, class V>
  503. inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, V > > >::type
  504. operator / (const detail::expression<detail::negate, number<B, et_on> >& a, const V& b)
  505. {
  506. return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, V > >(
  507. detail::expression<detail::divide_immediates, number<B, et_on>, V>(a.left_ref(), b));
  508. }
  509. template <class B, class B2, expression_template_option ET>
  510. inline typename enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >, detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B2, ET> > > >::type
  511. operator / (const detail::expression<detail::negate, number<B, et_on> >& a, const number<B2, ET>& b)
  512. {
  513. return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B2, ET> > >(
  514. detail::expression<detail::divide_immediates, number<B, et_on>, number<B2, ET> >(a.left_ref(), b));
  515. }
  516. template <class V, class B>
  517. inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >, detail::expression<detail::negate, detail::expression<detail::divide_immediates, V, number<B, et_on> > > >::type
  518. operator / (const V& a, const detail::expression<detail::negate, number<B, et_on> >& b)
  519. {
  520. return detail::expression<detail::negate, detail::expression<detail::divide_immediates, V, number<B, et_on> > >(
  521. detail::expression<detail::divide_immediates, V, number<B, et_on> >(a, b.left_ref()));
  522. }
  523. template <class B2, expression_template_option ET, class B>
  524. inline typename enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >, detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B2, ET>, number<B, et_on> > > >::type
  525. operator / (const number<B2, ET>& a, const detail::expression<detail::negate, number<B, et_on> >& b)
  526. {
  527. return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B2, ET>, number<B, et_on> > >(
  528. detail::expression<detail::divide_immediates, number<B2, ET>, number<B, et_on> >(a, b.left_ref()));
  529. }
  530. //
  531. // Modulus:
  532. //
  533. template <class B>
  534. inline typename enable_if_c<number_category<B>::value == number_kind_integer,
  535. detail::expression<detail::modulus_immediates, number<B, et_on>, number<B, et_on> > >::type
  536. operator % (const number<B, et_on>& a, const number<B, et_on>& b)
  537. {
  538. return detail::expression<detail::modulus_immediates, number<B, et_on>, number<B, et_on> >(a, b);
  539. }
  540. template <class B, class V>
  541. inline typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
  542. detail::expression<detail::modulus_immediates, number<B, et_on>, V > >::type
  543. operator % (const number<B, et_on>& a, const V& b)
  544. {
  545. return detail::expression<detail::modulus_immediates, number<B, et_on>, V >(a, b);
  546. }
  547. template <class V, class B>
  548. inline typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
  549. detail::expression<detail::modulus_immediates, V, number<B, et_on> > >::type
  550. operator % (const V& a, const number<B, et_on>& b)
  551. {
  552. return detail::expression<detail::modulus_immediates, V, number<B, et_on> >(a, b);
  553. }
  554. template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  555. inline typename enable_if_c<number_category<B>::value == number_kind_integer,
  556. detail::expression<detail::modulus, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
  557. operator % (const number<B, et_on>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
  558. {
  559. return detail::expression<detail::modulus, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
  560. }
  561. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
  562. inline typename enable_if_c<number_category<B>::value == number_kind_integer,
  563. detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> > >::type
  564. operator % (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, et_on>& b)
  565. {
  566. return detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b);
  567. }
  568. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
  569. inline typename enable_if_c<number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer,
  570. detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> > >::type
  571. operator % (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
  572. {
  573. return detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
  574. }
  575. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
  576. inline typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value
  577. && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
  578. detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V > >::type
  579. operator % (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
  580. {
  581. return detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b);
  582. }
  583. template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  584. inline typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value
  585. && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
  586. detail::expression<detail::modulus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
  587. operator % (const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
  588. {
  589. return detail::expression<detail::modulus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
  590. }
  591. //
  592. // Left shift:
  593. //
  594. template <class B, class I>
  595. inline typename enable_if_c<is_integral<I>::value && (number_category<B>::value == number_kind_integer), detail::expression<detail::shift_left, number<B, et_on>, I > >::type
  596. operator << (const number<B, et_on>& a, const I& b)
  597. {
  598. return detail::expression<detail::shift_left, number<B, et_on>, I>(a, b);
  599. }
  600. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class I>
  601. inline typename enable_if_c<is_integral<I>::value && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
  602. detail::expression<detail::shift_left, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, I> >::type
  603. operator << (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const I& b)
  604. {
  605. return detail::expression<detail::shift_left, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, I>(a, b);
  606. }
  607. //
  608. // Right shift:
  609. //
  610. template <class B, class I>
  611. inline typename enable_if_c<is_integral<I>::value && (number_category<B>::value == number_kind_integer),
  612. detail::expression<detail::shift_right, number<B, et_on>, I > >::type
  613. operator >> (const number<B, et_on>& a, const I& b)
  614. {
  615. return detail::expression<detail::shift_right, number<B, et_on>, I>(a, b);
  616. }
  617. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class I>
  618. inline typename enable_if_c<is_integral<I>::value
  619. && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
  620. detail::expression<detail::shift_right, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, I> >::type
  621. operator >> (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const I& b)
  622. {
  623. return detail::expression<detail::shift_right, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, I>(a, b);
  624. }
  625. //
  626. // Bitwise AND:
  627. //
  628. template <class B>
  629. inline typename enable_if_c<number_category<B>::value == number_kind_integer,
  630. detail::expression<detail::bitwise_and_immediates, number<B, et_on>, number<B, et_on> > >::type
  631. operator & (const number<B, et_on>& a, const number<B, et_on>& b)
  632. {
  633. return detail::expression<detail::bitwise_and_immediates, number<B, et_on>, number<B, et_on> >(a, b);
  634. }
  635. template <class B, class V>
  636. inline typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value
  637. && (number_category<B>::value == number_kind_integer),
  638. detail::expression<detail::bitwise_and_immediates, number<B, et_on>, V > >::type
  639. operator & (const number<B, et_on>& a, const V& b)
  640. {
  641. return detail::expression<detail::bitwise_and_immediates, number<B, et_on>, V >(a, b);
  642. }
  643. template <class V, class B>
  644. inline typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value
  645. && (number_category<B>::value == number_kind_integer),
  646. detail::expression<detail::bitwise_and_immediates, V, number<B, et_on> > >::type
  647. operator & (const V& a, const number<B, et_on>& b)
  648. {
  649. return detail::expression<detail::bitwise_and_immediates, V, number<B, et_on> >(a, b);
  650. }
  651. template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  652. inline typename enable_if_c<number_category<B>::value == number_kind_integer,
  653. detail::expression<detail::bitwise_and, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
  654. operator & (const number<B, et_on>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
  655. {
  656. return detail::expression<detail::bitwise_and, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
  657. }
  658. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
  659. inline typename enable_if_c<number_category<B>::value == number_kind_integer,
  660. detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> > >::type
  661. operator & (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, et_on>& b)
  662. {
  663. return detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b);
  664. }
  665. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
  666. inline typename enable_if_c<number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer,
  667. detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> > >::type
  668. operator & (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
  669. {
  670. return detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
  671. }
  672. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
  673. inline typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value
  674. && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
  675. detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V > >::type
  676. operator & (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
  677. {
  678. return detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b);
  679. }
  680. template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  681. inline typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value
  682. && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
  683. detail::expression<detail::bitwise_and, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
  684. operator & (const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
  685. {
  686. return detail::expression<detail::bitwise_and, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
  687. }
  688. //
  689. // Bitwise OR:
  690. //
  691. template <class B>
  692. inline typename enable_if_c<number_category<B>::value == number_kind_integer,
  693. detail::expression<detail::bitwise_or_immediates, number<B, et_on>, number<B, et_on> > >::type
  694. operator| (const number<B, et_on>& a, const number<B, et_on>& b)
  695. {
  696. return detail::expression<detail::bitwise_or_immediates, number<B, et_on>, number<B, et_on> >(a, b);
  697. }
  698. template <class B, class V>
  699. inline typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value
  700. && (number_category<B>::value == number_kind_integer),
  701. detail::expression<detail::bitwise_or_immediates, number<B, et_on>, V > >::type
  702. operator| (const number<B, et_on>& a, const V& b)
  703. {
  704. return detail::expression<detail::bitwise_or_immediates, number<B, et_on>, V >(a, b);
  705. }
  706. template <class V, class B>
  707. inline typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value
  708. && (number_category<B>::value == number_kind_integer),
  709. detail::expression<detail::bitwise_or_immediates, V, number<B, et_on> > >::type
  710. operator| (const V& a, const number<B, et_on>& b)
  711. {
  712. return detail::expression<detail::bitwise_or_immediates, V, number<B, et_on> >(a, b);
  713. }
  714. template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  715. inline typename enable_if_c<number_category<B>::value == number_kind_integer,
  716. detail::expression<detail::bitwise_or, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
  717. operator| (const number<B, et_on>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
  718. {
  719. return detail::expression<detail::bitwise_or, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
  720. }
  721. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
  722. inline typename enable_if_c<number_category<B>::value == number_kind_integer,
  723. detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> > >::type
  724. operator| (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, et_on>& b)
  725. {
  726. return detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b);
  727. }
  728. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
  729. inline typename enable_if_c<number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer,
  730. detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> > >::type
  731. operator| (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
  732. {
  733. return detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
  734. }
  735. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
  736. inline typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value
  737. && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
  738. detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V > >::type
  739. operator| (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
  740. {
  741. return detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b);
  742. }
  743. template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  744. inline typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value
  745. && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
  746. detail::expression<detail::bitwise_or, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
  747. operator| (const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
  748. {
  749. return detail::expression<detail::bitwise_or, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
  750. }
  751. //
  752. // Bitwise XOR:
  753. //
  754. template <class B>
  755. inline typename enable_if_c<number_category<B>::value == number_kind_integer,
  756. detail::expression<detail::bitwise_xor_immediates, number<B, et_on>, number<B, et_on> > >::type
  757. operator^ (const number<B, et_on>& a, const number<B, et_on>& b)
  758. {
  759. return detail::expression<detail::bitwise_xor_immediates, number<B, et_on>, number<B, et_on> >(a, b);
  760. }
  761. template <class B, class V>
  762. inline typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value
  763. && (number_category<B>::value == number_kind_integer),
  764. detail::expression<detail::bitwise_xor_immediates, number<B, et_on>, V > >::type
  765. operator^ (const number<B, et_on>& a, const V& b)
  766. {
  767. return detail::expression<detail::bitwise_xor_immediates, number<B, et_on>, V >(a, b);
  768. }
  769. template <class V, class B>
  770. inline typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value
  771. && (number_category<B>::value == number_kind_integer),
  772. detail::expression<detail::bitwise_xor_immediates, V, number<B, et_on> > >::type
  773. operator^ (const V& a, const number<B, et_on>& b)
  774. {
  775. return detail::expression<detail::bitwise_xor_immediates, V, number<B, et_on> >(a, b);
  776. }
  777. template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  778. inline typename enable_if_c<number_category<B>::value == number_kind_integer,
  779. detail::expression<detail::bitwise_xor, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
  780. operator^ (const number<B, et_on>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
  781. {
  782. return detail::expression<detail::bitwise_xor, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
  783. }
  784. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
  785. inline typename enable_if_c<number_category<B>::value == number_kind_integer,
  786. detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> > >::type
  787. operator^ (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, et_on>& b)
  788. {
  789. return detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b);
  790. }
  791. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
  792. inline typename enable_if_c<number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer,
  793. detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> > >::type
  794. operator^ (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
  795. {
  796. return detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
  797. }
  798. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
  799. inline typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value
  800. && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
  801. detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V > >::type
  802. operator^ (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
  803. {
  804. return detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b);
  805. }
  806. template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  807. inline typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value
  808. && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer), detail::expression<detail::bitwise_xor, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
  809. operator^ (const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
  810. {
  811. return detail::expression<detail::bitwise_xor, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
  812. }
  813. }} // namespaces
  814. #endif