Advertisement
Anna_Khashper

Untitled

Dec 5th, 2020 (edited)
505
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.59 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include <iostream>
  3.  
  4. // Определение списка целых чисел времени компиляции IntList
  5. template <int ... Ints>
  6. struct IntList;
  7.  
  8. template <int H, int ... I>
  9. struct IntList <H, I...>
  10. {
  11.   static int const Head = H;
  12.   using Tail = IntList<I...>;
  13. };
  14.  
  15. template <>
  16. struct IntList <> {};
  17.  
  18. template <typename IL>
  19. struct IntLength
  20. {
  21.   static int const value = 1 + IntLength <typename IL::Tail>::value;
  22. };
  23.  
  24. template <>
  25. struct IntLength <IntList<>>
  26. {
  27.   static int const value = 0;
  28. };
  29.  
  30. // добавление элемента в начало списка
  31. template<int H, typename IL>
  32. struct IntCons;
  33.  
  34. template<int H, int... Ints>
  35. struct IntCons<H, IntList<Ints...>>
  36. {
  37.   using type = IntList<H, Ints...>;
  38. };
  39.  
  40. // добавление элемента в конец списка
  41. template<typename IL, int N>
  42. struct IntAdd;
  43.  
  44. template<int... Ints, int N>
  45. struct IntAdd<IntList<Ints...>, N>
  46. {
  47.   using type = IntList<Ints..., N>;
  48. };
  49.  
  50. template <int N, typename IL = IntList<>>
  51. struct Generate;
  52.  
  53. template <int N, int... Ints>
  54. struct Generate <N, IntList<Ints...>>
  55. {
  56.   using type = typename IntAdd<typename Generate<N - 1, IntList<>>::type, N - 1>::type;
  57. };
  58.  
  59. template<>
  60. struct Generate<0>
  61. {
  62.   static const int length = 0;
  63.   using type = IntList<>;
  64. };
  65.  
  66. template <typename IL1, typename IL2, template<int, int> class f>
  67. struct Zip
  68. {
  69.   using type = typename IntCons<f<IL1::Head, IL2::Head>::value, typename Zip <typename IL1::Tail, typename IL2::Tail, f>::type>::type;
  70. };
  71.  
  72. template<template<int, int> class f>
  73. struct Zip<IntList<>, IntList<>, f>
  74. {
  75.   using type = IntList<>;
  76. };
  77.  
  78. template <int T>
  79. void print_ints(std::ostream& out)
  80. {
  81.   out << T;
  82. }
  83.  
  84. template <int T, int U, int... Args>
  85. void print_ints(std::ostream& out)
  86. {
  87.   out << T << ' ';
  88.   print_ints<U, Args...>(out);
  89. }
  90.  
  91. template<typename>
  92. struct pretty;
  93.  
  94. template<int... Ints>
  95. struct pretty< IntList<Ints...> >
  96. {
  97.   static void print()
  98.   {
  99.     ::print_ints<Ints...>(std::cout);
  100.   }
  101. };
  102.  
  103. template<int m = 0, int kg = 0, int s = 0, int A = 0, int K = 0, int mol = 0, int cd = 0>
  104. using Dimension = IntList<m, kg, s, A, K, mol, cd>;
  105.  
  106. template<typename Object>
  107. class Quantity;
  108.  
  109. template<int a, int b>
  110. struct Plus {
  111.     static const int value = a + b;
  112. };
  113.  
  114. template<int a, int b>
  115. struct Minus {
  116.     static const int value = a - b;
  117. };
  118.  
  119. template<int...Args>
  120. class Quantity<IntList<Args...>> {
  121. public:
  122.     Quantity() :val(0) {}
  123.     explicit Quantity(double x) :val(x) {}
  124.     double value() const { return val; }
  125.     Quantity<IntList<Args...>>& operator += (const Quantity<IntList<Args...>>& rhs)
  126.     {
  127.         val += rhs.val;
  128.         return *this;
  129.     }
  130.     Quantity<IntList<Args...>>& operator -= (const Quantity<IntList<Args...>>& rhs)
  131.     {
  132.         val -= rhs.val;
  133.         return *this;
  134.     }
  135.     Quantity<IntList<Args...>>& operator *= (double rhs)
  136.     {
  137.         val *= rhs;
  138.         return *this;
  139.     }
  140.     Quantity<IntList<Args...>>& operator /= (double rhs)
  141.     {
  142.         val /= rhs;
  143.         return *this;
  144.     }
  145. private:
  146.     double val;
  147.    
  148. };
  149.  
  150. // Quantity + Quantity
  151. template<int ...Args>
  152. const Quantity <IntList<Args...>> operator+(const Quantity<IntList<Args...>>& lhs,
  153.     const Quantity<IntList<Args...>>& rhs)
  154. {
  155.     Quantity<IntList<Args...>> result(lhs);
  156.     return result += rhs;
  157. }
  158.  
  159. // Quantity - Quantity
  160. template<int ...Args>
  161. const Quantity <IntList<Args...>> operator-(const Quantity<IntList<Args...>>& lhs,
  162.     const Quantity<IntList<Args...>>& rhs)
  163. {
  164.     Quantity<IntList<Args...>> result(lhs);
  165.     return result -= rhs;
  166. }
  167.  
  168. // double * Quantity
  169. template<int ...Args>
  170. const Quantity <IntList<Args...>> operator*(double lhs,
  171.     const Quantity <IntList<Args...>>& rhs)
  172. {
  173.     Quantity <IntList<Args...>> result(rhs);
  174.     return result *= lhs;
  175. }
  176.  
  177. // Quantity * double
  178. template<int ...Args>
  179. const Quantity <IntList<Args...>> operator*(const Quantity <IntList<Args...>>& lhs,
  180.     double rhs)
  181. {
  182.     Quantity <IntList<Args...>> result(lhs);
  183.     return result *= rhs;
  184. }
  185.  
  186. // Quantity * Quantity
  187. template< int ...Args1, int ...Args2>
  188. const Quantity<IntList<(Args1 + Args2)...>>
  189.     operator*(const Quantity<IntList<Args1...>>& lhs,
  190.         const Quantity<IntList<Args2...>>& rhs)
  191. {
  192.     using ResList = typename Zip<IntList<Args1...>, IntList<Args2...>, Plus>::type;
  193.     using ResType = Quantity<ResList>;
  194.     return ResType(lhs.value() * rhs.value());
  195. }
  196.  
  197. // Quantity / double
  198. template<int ...Args>
  199. const Quantity <IntList<Args...>> operator/(const Quantity <IntList<Args...>>& lhs,
  200.     double rhs)
  201. {
  202.     Quantity <IntList<Args...>> result(lhs);
  203.     return result /= rhs;
  204. }
  205.  
  206. // Quantity / Quantity
  207. template< int ...Args1, int ...Args2>
  208.     const Quantity<IntList<(Args1 - Args2)...>>
  209.     operator/(const Quantity<IntList<Args1...>>& lhs,
  210.         const Quantity<IntList<Args2...>>& rhs)
  211. {
  212.     using ResList = typename Zip<IntList<Args1...>, IntList<Args2...>, Minus>::type;
  213.     using ResType = Quantity<ResList>;
  214.     return ResType(lhs.value() / rhs.value());
  215. }
  216.  
  217. // double / Quantity
  218. template<int ...Args>
  219. const double operator/(double lhs,
  220.     const Quantity <IntList<Args...>>& rhs)
  221. {
  222.     using ResList = typename Zip<Dimension<>, IntList<Args...>, Minus>::type;
  223.     //using ResType = Quantity<ResList>;
  224.     //return ResType(lhs/rhs.value());
  225.     return lhs / rhs.value();
  226. }
  227.  
  228. using NumberQ = Quantity<Dimension<>>;          // число без размерности
  229. using LengthQ = Quantity<Dimension<1>>;          // метры
  230. using MassQ = Quantity<Dimension<0, 1>>;       // килограммы
  231. using TimeQ = Quantity<Dimension<0, 0, 1>>;    // секунды
  232. using VelocityQ = Quantity<Dimension<1, 0, -1>>;   // метры в секунду
  233. using AccelQ = Quantity<Dimension<1, 0, -2>>;   // ускорение, метры в секунду в квадрате
  234. using ForceQ = Quantity<Dimension<1, 1, -2>>;   // сила в ньютонах
  235.  
  236. int main()
  237. {
  238.   // два списка одной длины
  239.   using L1 = IntList<1, 2, 3, 4, 5>;
  240.   using L2 = IntList<1, 3, 7, 7, 2>;
  241.  
  242.   // результат применения — список с поэлементными суммами
  243.   using L3 = Zip<L1, L2, Plus>::type;  // IntList<2, 5, 10, 11, 7>
  244.   pretty<L3>::print();
  245.  
  246.   LengthQ   l{ 30000 };      // 30 км
  247.   TimeQ     t{ 10 * 60 };    // 10 минут
  248.                              // вычисление скорости
  249.   VelocityQ v = l / t;     // результат типа VelocityQ, 50 м/с
  250.  
  251.   AccelQ    a{ 9.8 };        // ускорение свободного падения
  252.   MassQ     m{ 80 };         // 80 кг
  253.                              // сила притяжения, которая действует на тело массой 80 кг
  254.   ForceQ    f = m * a;     // результат типа ForceQ
  255.  
  256.   return 0;
  257. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement