点击查看代码
#include <iostream>
#include <tuple>
struct IntType;
template<int N>
struct Int {
static const int value = N;
typedef IntType typetype;
typedef Int type;
template<typename T>
auto operator+(const T& t) const -> Int<T::value + value> {
static_assert(std::is_same<typetype, typename T::typetype>::value, "type is different");
return Int<T::value + value>();
}
template<typename T>
auto operator-(const T& t) const -> Int<T::value - value> {
static_assert(std::is_same<typetype, typename T::typetype>::value, "type is different");
return Int<T::value - value>();
}
};
template<typename T, typename Dimensions>
struct tquantity {
typedef Dimensions type;
typedef T value_type;
explicit tquantity(T x) : value_(x) {}
const T& value() const { return value_; }
private:
T value_;
};
typedef std::tuple<Int<0>, Int<0>, Int<0>, Int<0>, Int<0>, Int<0>, Int<0>> tscalar;
typedef std::tuple<Int<1>, Int<0>, Int<0>, Int<0>, Int<0>, Int<0>, Int<0>> tmass;
typedef std::tuple<Int<0>, Int<1>, Int<0>, Int<0>, Int<0>, Int<0>, Int<0>> tlength;
typedef std::tuple<Int<0>, Int<0>, Int<1>, Int<0>, Int<0>, Int<0>, Int<0>> ttime;
typedef std::tuple<Int<0>, Int<0>, Int<0>, Int<1>, Int<0>, Int<0>, Int<0>> tcharge;
typedef std::tuple<Int<0>, Int<0>, Int<0>, Int<0>, Int<1>, Int<0>, Int<0>> ttemperature;
typedef std::tuple<Int<0>, Int<0>, Int<0>, Int<0>, Int<0>, Int<1>, Int<0>> tintensity;
typedef std::tuple<Int<0>, Int<0>, Int<0>, Int<0>, Int<0>, Int<0>, Int<1>> tamount_of_substance;
typedef std::tuple<Int<0>, Int<1>, Int<-1>, Int<0>, Int<0>, Int<0>, Int<0>> tvelocity;
typedef std::tuple<Int<0>, Int<1>, Int<-2>, Int<0>, Int<0>, Int<0>, Int<0>> tacceleration;
typedef std::tuple<Int<1>, Int<1>, Int<-1>, Int<0>, Int<0>, Int<0>, Int<0>> tmomentum;
typedef std::tuple<Int<1>, Int<1>, Int<-2>, Int<0>, Int<0>, Int<0>, Int<0>> tforce;
template<typename T = tscalar, typename D = tscalar>
struct DimensionsBinaryOperatorPlus {
// static_assert(
// std::is_same<typename decltype(std::get<0>(T()))::typetype, typename decltype(std::get<0>(D()))::typetype>::value &&
// std::is_same<typename decltype(std::get<1>(T()))::typetype, typename decltype(std::get<1>(D()))::typetype>::value &&
// std::is_same<typename decltype(std::get<2>(T()))::typetype, typename decltype(std::get<2>(D()))::typetype>::value &&
// std::is_same<typename decltype(std::get<3>(T()))::typetype, typename decltype(std::get<3>(D()))::typetype>::value &&
// std::is_same<typename decltype(std::get<4>(T()))::typetype, typename decltype(std::get<4>(D()))::typetype>::value &&
// std::is_same<typename decltype(std::get<5>(T()))::typetype, typename decltype(std::get<5>(D()))::typetype>::value &&
// std::is_same<typename decltype(std::get<6>(T()))::typetype, typename decltype(std::get<6>(D()))::typetype>::value,
// "DimensionsBinaryOperatorPlus typetype is different");
typedef std::tuple<
decltype(std::get<0>(T()) + std::get<0>(D())),
decltype(std::get<1>(T()) + std::get<1>(D())),
decltype(std::get<2>(T()) + std::get<2>(D())),
decltype(std::get<3>(T()) + std::get<3>(D())),
decltype(std::get<4>(T()) + std::get<4>(D())),
decltype(std::get<5>(T()) + std::get<5>(D())),
decltype(std::get<6>(T()) + std::get<6>(D()))
> type;
};
template<typename T = tscalar, typename D = tscalar>
struct DimensionsBinaryOperatorMinus {
// static_assert(
// std::is_same<typename decltype(std::get<0>(T()))::typetype, typename decltype(std::get<0>(D()))::typetype>::value &&
// std::is_same<typename decltype(std::get<1>(T()))::typetype, typename decltype(std::get<1>(D()))::typetype>::value &&
// std::is_same<typename decltype(std::get<2>(T()))::typetype, typename decltype(std::get<2>(D()))::typetype>::value &&
// std::is_same<typename decltype(std::get<3>(T()))::typetype, typename decltype(std::get<3>(D()))::typetype>::value &&
// std::is_same<typename decltype(std::get<4>(T()))::typetype, typename decltype(std::get<4>(D()))::typetype>::value &&
// std::is_same<typename decltype(std::get<5>(T()))::typetype, typename decltype(std::get<5>(D()))::typetype>::value &&
// std::is_same<typename decltype(std::get<6>(T()))::typetype, typename decltype(std::get<6>(D()))::typetype>::value,
// "DimensionsBinaryOperatorMinus typetype is different");
typedef std::tuple<
decltype(std::get<0>(T()) - std::get<0>(D())),
decltype(std::get<1>(T()) - std::get<1>(D())),
decltype(std::get<2>(T()) - std::get<2>(D())),
decltype(std::get<3>(T()) - std::get<3>(D())),
decltype(std::get<4>(T()) - std::get<4>(D())),
decltype(std::get<5>(T()) - std::get<5>(D())),
decltype(std::get<6>(T()) - std::get<6>(D()))
> type;
};
template<typename T = tscalar, typename D = tscalar, typename BinaryOperator = DimensionsBinaryOperatorPlus<T, D>>
struct DimensionsTypeOperator {
typedef typename BinaryOperator::type type;
};
template<typename T1, typename T2>
tquantity<typename T1::value_type, typename T1::type> operator+(const T1& lhs, const T2& rhs) {
static_assert(std::is_same<typename T1::type, typename T2::type>::value, "T1::type must be same as T2::type");
return tquantity<typename T1::value_type, typename T1::type>(lhs.value() + rhs.value());
}
template<typename T1, typename T2>
tquantity<typename T1::value_type, typename T1::type> operator-(const T1& lhs, const T2& rhs) {
static_assert(std::is_same<typename T1::type, typename T2::type>::value, "T1::type must be same as T2::type");
return tquantity<typename T1::value_type, typename T1::type>(lhs.value() - rhs.value());
}
template<typename T1, typename T2>
tquantity<typename T1::value_type, typename DimensionsTypeOperator<typename T1::type, typename T2::type>::type>
operator*(const T1& lhs, const T2& rhs) {
typedef typename DimensionsTypeOperator<typename T1::type, typename T2::type>::type type;
return tquantity<typename T1::value_type, type>(lhs.value() + rhs.value());
}
template<typename T1, typename T2>
tquantity<typename T1::value_type,
typename DimensionsTypeOperator<typename T1::type, typename T2::type,
DimensionsBinaryOperatorMinus<typename T1::type, typename T2::type>>::type>
operator/(const T1& lhs, const T2& rhs) {
typedef typename DimensionsTypeOperator<typename T1::type, typename T2::type,
DimensionsBinaryOperatorMinus<typename T1::type, typename T2::type>>::type type;
return tquantity<typename T1::value_type, type>(lhs.value() / rhs.value());
}
void quantity_test() {
tquantity<float, tmass> m(0.5f);
tquantity<float, tacceleration> a(9.8f);
tquantity<float, tforce> f = m * a;
std::cout << "operator + test:" << (m + m).value() << std::endl;
std::cout << "operator - test:" << (m - m).value() << std::endl;
std::cout << "operator * test:" << (m * a).value() << std::endl;
std::cout << "operator / test:" << (m / a).value() << std::endl;
}
int main() {
quantity_test();
return 0;
}
点击查看代码
#include <iostream>
#include <type_traits>
using namespace std;
#if __cplusplus <= 201103L
template< bool B, class T, class F >
using conditional_t = typename conditional<B,T,F>::type;
#endif
template<typename T>
struct DelayCalcType {
using type = T;
};
template<int ... N> struct seq {};
template<typename T1, typename T2, int pos> struct split;
template<int F, int ... N1, int ... N2>
struct split<seq<F, N1...>, seq<N2...>, 0> {
using second = seq<N1...>;
using first = seq<N2...>;
using mid = seq<F>;
};
template<int F, int ... N1, int ... N2, int pos>
struct split<seq<F, N1...>, seq<N2...>, pos> : split<seq<N1...>, seq<N2..., F>, pos - 1> {};
template<typename T1, typename T2> struct merge;
template<int ... N1, int ... N2>
struct merge<seq<N1...>, seq<N2...>> {
using type = seq<N1..., N2...>;
};
template<typename T, int pos> struct get;
template<int F, int ... N>
struct get<seq<F, N...>, 0> {
static constexpr int value = F;
};
template<int F, int ... N, int pos>
struct get<seq<F, N...>, pos> {
static constexpr int value = get<seq<N...>, pos - 1>::value;
};
template<int l, int r, typename T> struct seq_swap;
template<int l, int ... N>
struct seq_swap<l, l, seq<N...>> {
using type = seq<N...>;
};
template<int l, int r, int ... N>
struct seq_swap<l, r, seq<N...>> {
private:
using ltype = split<seq<N...>, seq<>, l>;
using ltype1 = typename ltype::first;
using ltype2 = typename ltype::mid;
using rtype = split<typename ltype::second, seq<>, r - l - 1>;
using rtype1 = typename rtype::first;
using rtype2 = typename rtype::mid;
using etype = typename rtype::second;
public:
using type =
typename merge<
typename merge<
typename merge<ltype1, rtype2>::type,
typename merge<rtype1, ltype2>::type
>::type,
etype
>::type;
};
template<typename T, int pos> struct up;
template<int ... N>
struct up<seq<N...>, 0> {
using type = seq<N...>;
};
template<int pos, int ... N>
struct up<seq<N...>, pos> {
using type = conditional_t<get<seq<N...>, (pos - 1) / 2>::value <= get<seq<N...>, pos>::value, seq<N...>,
typename up<typename seq_swap<(pos - 1) / 2, pos, seq<N...>>::type, (pos - 1) / 2>::type>;
};
template<typename T, int pos, int epos> struct down;
template<int ... N, int pos>
struct down<seq<N...>, pos, pos> {
using type = seq<N...>;
};
template<typename T, int l, int r> struct get_pos;
template<int ... N, int l, int r>
struct get_pos<seq<N...>, l, r> {
static constexpr int value = get<seq<N...>, l>::value <= get<seq<N...>, r>::value ? l : r;
};
template<int pos, int p2, int epos, typename T> struct delay_down;
template<int pos, int p2, int epos, int ... N>
struct delay_down<pos, p2, epos, seq<N...>> {
using type = typename down<
typename seq_swap<pos, p2, seq<N...>>::type,
p2, epos
>::type;
};
template<int ... N, int pos, int epos>
struct down<seq<N...>, pos, epos> {
// private:
static constexpr int p = pos;
using pt1 = conditional_t<pos * 2 + 1 < epos,
DelayCalcType<get_pos<seq<N...>, pos, pos * 2 + 1>>,
DelayCalcType<get<seq<pos>, 0>>>;
static constexpr int p1 = pt1::type::value;
using pt2 = conditional_t<pos * 2 + 2 < epos,
DelayCalcType<get_pos<seq<N...>, pos * 2 + 2, p1>>,
DelayCalcType<get<seq<p1>, 0>>>;
static constexpr int p2 = pt2::type::value;
public:
using type = typename conditional_t<
pos == p2,
DelayCalcType<seq<N...>>,
delay_down<pos, p2, epos, seq<N...>>
>::type;
};
template<typename T, int pos, int epos> struct build;
template<int ... N, int epos>
struct build<seq<N...>, 0, epos> {
using type = typename down<seq<N...>, 0, epos>::type;
};
template<int ... N, int pos, int epos>
struct build<seq<N...>, pos, epos> {
private:
using ttype = typename down<seq<N...>, pos, epos>::type;
public:
using type = typename build<ttype, pos - 1, epos>::type;
};
template<typename T, typename ans, int epos, bool build_flg = false> struct heap_sort;
template<int F, int ... N, int ... C, bool flg>
struct heap_sort<seq<F, N...>, seq<C...>, 0, flg> {
using type = seq<C...>;
using type1 = seq<F, N...>;
};
template<int F, int ... N, int ... C, int epos, bool flg>
struct heap_sort<seq<F, N...>, seq<C...>, epos, flg> {
private:
using ttype = typename
conditional_t<flg == false, build<seq<F, N...>, epos - 1, epos>, DelayCalcType<seq<F, N...>>>::type;
using ttype1 = seq<C..., get<ttype, 0>::value>;
using ttype2 = typename seq_swap<0, epos - 1, ttype>::type;
using ttype3 = typename down<ttype2, 0, epos - 1>::type;
public:
using type = typename heap_sort<ttype3, ttype1, epos - 1, true>::type;
using type1 = typename heap_sort<ttype3, ttype1, epos - 1, true>::type1;
};
template<int ...N>
void print(const seq<N...>&) {
static int args[] = {N...};
for (int i = 0; i < sizeof args / sizeof(int); ++i)
cout << args[i] << ' ';
cout << endl;
}
int main() {
seq<3, 6, 7, 4, 2, 8, 1> s;
cout << get<seq<3, 6, 7, 4, 2, 8, 1>, 0>::value << endl;
cout << get<seq<3, 6, 7, 4, 2, 8, 1>, 1>::value << endl;
cout << get<seq<3, 6, 7, 4, 2, 8, 1>, 2>::value << endl;
cout << get<seq<3, 6, 7, 4, 2, 8, 1>, 3>::value << endl;
cout << get<seq<3, 6, 7, 4, 2, 8, 1>, 4>::value << endl;
cout << get<seq<3, 6, 7, 4, 2, 8, 1>, 5>::value << endl;
// split<seq<3, 6, 7, 4, 2, 8, 1>, seq<>, 3>
print(split<seq<3, 6, 7, 4, 2, 8, 1>, seq<>, 3>::first());
print(split<seq<3, 6, 7, 4, 2, 8, 1>, seq<>, 3>::second());
cout << "----" << endl;
print(seq<3, 6, 7, 4, 2, 8, 1>());
print(seq_swap<1, 5, seq<3, 6, 7, 4, 2, 8, 1>>::type());
print(up<seq<3, 6, 7, 4, 2, 8, 1>, 3>::type());
print(down<seq<13, 6, 7, 4, 2, 8, 1>, 1, 7>::type());
// print(build<seq<13, 6, 7, 4, 2, 8, 1>, 6, 7>::ttype());
// print(build<seq<13, 6, 7, 4, 2, 8, 1>, 5, 7>::ttype());
// print(build<seq<13, 6, 7, 4, 2, 8, 1>, 4, 7>::ttype());
// print(build<seq<13, 6, 7, 4, 2, 8, 1>, 3, 7>::ttype());
// print(build<seq<13, 6, 7, 4, 2, 8, 1>, 2, 7>::ttype());
// print(build<seq<13, 6, 7, 4, 2, 8, 1>, 1, 7>::ttype());
print(build<seq<13, 6, 7, 4, 2, 8, 1>, 6, 7>::type());
cout << down<seq<13, 6, 7, 4, 2, 8, 1>, 1, 7>::p1 << ' ' << down<seq<13, 6, 7, 4, 2, 8, 1>, 3, 7>::p2 << endl;
cout << "----" << endl;
cout << "final test" << endl;
print(heap_sort<seq<13, 6, 7, 4, 2, 8, 1>, seq<>, 7, false>::type());
print(heap_sort<seq<13, 6, 7, 4, 2, 8, 1>, seq<>, 7, false>::type1());
print(heap_sort<seq<5, 7, 4, 2, 8, 6, 1, 9, 0, 3>, seq<>, 10, false>::type());
print(heap_sort<seq<5, 7, 4, 2, 8, 6, 1, 9, 0, 3>, seq<>, 10, false>::type1());
print(heap_sort<seq<3, 6, 7, 4, 2, 8, 1>, seq<>, 7, false>::type());
print(heap_sort<seq<3, 6, 7, 4, 2, 8, 1>, seq<>, 7, false>::type1());
return 0;
}