Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "stdafx.h"
- #include <iostream>
- // Определение списка целых чисел времени компиляции IntList
- template <int ... Ints>
- struct IntList;
- template <int H, int ... I>
- struct IntList <H, I...>
- {
- static int const Head = H;
- using Tail = IntList<I...>;
- };
- template <>
- struct IntList <> {};
- template <typename IL>
- struct IntLength
- {
- static int const value = 1 + IntLength <typename IL::Tail>::value;
- };
- template <>
- struct IntLength <IntList<>>
- {
- static int const value = 0;
- };
- // добавление элемента в начало списка
- template<int H, typename IL>
- struct IntCons;
- template<int H, int... Ints>
- struct IntCons<H, IntList<Ints...>>
- {
- using type = IntList<H, Ints...>;
- };
- // добавление элемента в конец списка
- template<typename IL, int N>
- struct IntAdd;
- template<int... Ints, int N>
- struct IntAdd<IntList<Ints...>, N>
- {
- using type = IntList<Ints..., N>;
- };
- template <int N, typename IL = IntList<>>
- struct Generate;
- template <int N, int... Ints>
- struct Generate <N, IntList<Ints...>>
- {
- using type = typename IntAdd<typename Generate<N - 1, IntList<>>::type, N - 1>::type;
- };
- template<>
- struct Generate<0>
- {
- static const int length = 0;
- using type = IntList<>;
- };
- template <typename IL1, typename IL2, template<int, int> class f>
- struct Zip
- {
- using type = typename IntCons<f<IL1::Head, IL2::Head>::value, typename Zip <typename IL1::Tail, typename IL2::Tail, f>::type>::type;
- };
- template<template<int, int> class f>
- struct Zip<IntList<>, IntList<>, f>
- {
- using type = IntList<>;
- };
- template <int T>
- void print_ints(std::ostream& out)
- {
- out << T;
- }
- template <int T, int U, int... Args>
- void print_ints(std::ostream& out)
- {
- out << T << ' ';
- print_ints<U, Args...>(out);
- }
- template<typename>
- struct pretty;
- template<int... Ints>
- struct pretty< IntList<Ints...> >
- {
- static void print()
- {
- ::print_ints<Ints...>(std::cout);
- }
- };
- template<int m = 0, int kg = 0, int s = 0, int A = 0, int K = 0, int mol = 0, int cd = 0>
- using Dimension = IntList<m, kg, s, A, K, mol, cd>;
- template<typename Object>
- class Quantity;
- template<int a, int b>
- struct Plus {
- static const int value = a + b;
- };
- template<int a, int b>
- struct Minus {
- static const int value = a - b;
- };
- template<int...Args>
- class Quantity<IntList<Args...>> {
- public:
- Quantity() :val(0) {}
- explicit Quantity(double x) :val(x) {}
- double value() const { return val; }
- Quantity<IntList<Args...>>& operator += (const Quantity<IntList<Args...>>& rhs)
- {
- val += rhs.val;
- return *this;
- }
- Quantity<IntList<Args...>>& operator -= (const Quantity<IntList<Args...>>& rhs)
- {
- val -= rhs.val;
- return *this;
- }
- Quantity<IntList<Args...>>& operator *= (double rhs)
- {
- val *= rhs;
- return *this;
- }
- Quantity<IntList<Args...>>& operator /= (double rhs)
- {
- val /= rhs;
- return *this;
- }
- private:
- double val;
- };
- // Quantity + Quantity
- template<int ...Args>
- const Quantity <IntList<Args...>> operator+(const Quantity<IntList<Args...>>& lhs,
- const Quantity<IntList<Args...>>& rhs)
- {
- Quantity<IntList<Args...>> result(lhs);
- return result += rhs;
- }
- // Quantity - Quantity
- template<int ...Args>
- const Quantity <IntList<Args...>> operator-(const Quantity<IntList<Args...>>& lhs,
- const Quantity<IntList<Args...>>& rhs)
- {
- Quantity<IntList<Args...>> result(lhs);
- return result -= rhs;
- }
- // double * Quantity
- template<int ...Args>
- const Quantity <IntList<Args...>> operator*(double lhs,
- const Quantity <IntList<Args...>>& rhs)
- {
- Quantity <IntList<Args...>> result(rhs);
- return result *= lhs;
- }
- // Quantity * double
- template<int ...Args>
- const Quantity <IntList<Args...>> operator*(const Quantity <IntList<Args...>>& lhs,
- double rhs)
- {
- Quantity <IntList<Args...>> result(lhs);
- return result *= rhs;
- }
- // Quantity * Quantity
- template< int ...Args1, int ...Args2>
- const Quantity<IntList<(Args1 + Args2)...>>
- operator*(const Quantity<IntList<Args1...>>& lhs,
- const Quantity<IntList<Args2...>>& rhs)
- {
- using ResList = typename Zip<IntList<Args1...>, IntList<Args2...>, Plus>::type;
- using ResType = Quantity<ResList>;
- return ResType(lhs.value() * rhs.value());
- }
- // Quantity / double
- template<int ...Args>
- const Quantity <IntList<Args...>> operator/(const Quantity <IntList<Args...>>& lhs,
- double rhs)
- {
- Quantity <IntList<Args...>> result(lhs);
- return result /= rhs;
- }
- // Quantity / Quantity
- template< int ...Args1, int ...Args2>
- const Quantity<IntList<(Args1 - Args2)...>>
- operator/(const Quantity<IntList<Args1...>>& lhs,
- const Quantity<IntList<Args2...>>& rhs)
- {
- using ResList = typename Zip<IntList<Args1...>, IntList<Args2...>, Minus>::type;
- using ResType = Quantity<ResList>;
- return ResType(lhs.value() / rhs.value());
- }
- // double / Quantity
- template<int ...Args>
- const double operator/(double lhs,
- const Quantity <IntList<Args...>>& rhs)
- {
- using ResList = typename Zip<Dimension<>, IntList<Args...>, Minus>::type;
- //using ResType = Quantity<ResList>;
- //return ResType(lhs/rhs.value());
- return lhs / rhs.value();
- }
- using NumberQ = Quantity<Dimension<>>; // число без размерности
- using LengthQ = Quantity<Dimension<1>>; // метры
- using MassQ = Quantity<Dimension<0, 1>>; // килограммы
- using TimeQ = Quantity<Dimension<0, 0, 1>>; // секунды
- using VelocityQ = Quantity<Dimension<1, 0, -1>>; // метры в секунду
- using AccelQ = Quantity<Dimension<1, 0, -2>>; // ускорение, метры в секунду в квадрате
- using ForceQ = Quantity<Dimension<1, 1, -2>>; // сила в ньютонах
- int main()
- {
- // два списка одной длины
- using L1 = IntList<1, 2, 3, 4, 5>;
- using L2 = IntList<1, 3, 7, 7, 2>;
- // результат применения — список с поэлементными суммами
- using L3 = Zip<L1, L2, Plus>::type; // IntList<2, 5, 10, 11, 7>
- pretty<L3>::print();
- LengthQ l{ 30000 }; // 30 км
- TimeQ t{ 10 * 60 }; // 10 минут
- // вычисление скорости
- VelocityQ v = l / t; // результат типа VelocityQ, 50 м/с
- AccelQ a{ 9.8 }; // ускорение свободного падения
- MassQ m{ 80 }; // 80 кг
- // сила притяжения, которая действует на тело массой 80 кг
- ForceQ f = m * a; // результат типа ForceQ
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement