QuickSort.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #include <tuple>
  2. #include <type_traits>
  3. #include <iostream>
  4. using std::tuple;
  5. using std::integral_constant;
  6. using std::is_same;
  7. template <int... values> struct to_int_types{
  8. typedef tuple< integral_constant<int, values>... > type;
  9. };
  10. template <typename Pivot> struct Less {
  11. template <typename X> struct Apply {
  12. static bool const value = X::value < Pivot::value;
  13. };
  14. };
  15. template <typename Pivot> struct GE {
  16. template <typename X> struct Apply {
  17. static bool const value = X::value >= Pivot::value;
  18. };
  19. };
  20. template <typename x, bool realAdd, typename tuple> struct Tuple_PushFront {};
  21. template <typename x, typename... tupleElems> struct Tuple_PushFront<x, true, tuple<tupleElems...>> {
  22. typedef tuple<x, tupleElems...> type;
  23. };
  24. template <typename x, typename... tupleElems> struct Tuple_PushFront<x, false, tuple<tupleElems...>> {
  25. typedef tuple<tupleElems...> type;
  26. };
  27. template <typename Pred, typename tuple> struct Filter;
  28. template <typename Pred> struct Filter< Pred, tuple<> > {
  29. typedef tuple<> type;
  30. };
  31. template <typename Pred, typename Head, typename... Ts> struct Filter< Pred, tuple<Head, Ts...> > {
  32. typedef typename Tuple_PushFront<
  33. Head, Pred::template Apply<Head>::value, typename Filter<Pred, tuple<Ts...>>::type
  34. >::type type;
  35. };
  36. template <typename... Tuples> struct ConcatenateTuple {};
  37. template <typename Tuple0> struct ConcatenateTuple<Tuple0> {
  38. typedef Tuple0 type;
  39. };
  40. template <typename Tuple0, typename Tuple1> struct ConcatenateTuple<Tuple0, Tuple1> {
  41. template <typename TupleA> struct ConcatenateImpl {};
  42. template <typename... TAs> struct ConcatenateImpl< tuple<TAs...> > {
  43. template <typename TupleB> struct Apply;
  44. template <typename... TBs> struct Apply< tuple<TBs...> > {
  45. typedef tuple<TAs..., TBs...> type;
  46. };
  47. };
  48. typedef typename ConcatenateImpl<Tuple0>::template Apply<Tuple1>::type type;
  49. };
  50. template <typename FirstTuple, typename... Follows> struct ConcatenateTuple<FirstTuple, Follows...> {
  51. typedef typename ConcatenateTuple<
  52. FirstTuple, typename ConcatenateTuple<Follows...>::type
  53. >::type type;
  54. };
  55. template <typename tuple> struct QuickSort {};
  56. template <> struct QuickSort< tuple< > > { typedef tuple< > type; };
  57. template <typename T0> struct QuickSort< tuple<T0> > { typedef tuple<T0> type; };
  58. template <typename Head, typename... Ts>
  59. struct QuickSort< tuple<Head, Ts...> > {
  60. typedef typename Filter< Less<Head>, tuple<Ts...> >::type LeftElems;
  61. typedef typename Filter< GE <Head>, tuple<Ts...> >::type RightElems;
  62. typedef typename ConcatenateTuple<
  63. typename QuickSort<LeftElems>::type, tuple<Head>, typename QuickSort<RightElems>::type
  64. >::type type;
  65. };
  66. void StaticTest()
  67. {
  68. typedef to_int_types<1, 2, 3>::type lst_1_3;
  69. typedef to_int_types<3, 2, 1>::type lst_3_1;
  70. typedef to_int_types<3, 7, 1, 6, 5, 22, 5>::type lst;
  71. typedef to_int_types<1, 3, 5, 5, 6, 7, 22>::type sorted_lst;
  72. typedef integral_constant<int, 1>::type i1;
  73. typedef integral_constant<int, 2>::type i2;
  74. typedef integral_constant<int, 3>::type i3;
  75. static_assert(Less<i2>::Apply<i1>::value == true, "");
  76. static_assert(Less<i1>::Apply<i1>::value == false, "");
  77. static_assert(Less<i1>::Apply<i2>::value == false, "");
  78. static_assert(GE<i2>::Apply<i3>::value == true, "");
  79. static_assert(GE<i2>::Apply<i2>::value == true, "");
  80. static_assert(GE<i3>::Apply<i2>::value == false, "");
  81. static_assert(is_same<Tuple_PushFront<i1, true, tuple<i2>>::type, tuple<i1, i2>>::value, "");
  82. static_assert(is_same<Tuple_PushFront<i2, true, tuple<i1>>::type, tuple<i2, i1>>::value, "");
  83. static_assert(is_same<Tuple_PushFront<i2, false, tuple<i1>>::type, tuple<i1>>::value, "");
  84. static_assert(is_same<Filter<Less<i2>, lst_1_3>::type, tuple<i1>>::value, "");
  85. static_assert(is_same<QuickSort<lst_1_3 >::type, lst_1_3>::value, "");
  86. static_assert(is_same<QuickSort<lst_3_1 >::type, lst_1_3>::value, "");
  87. static_assert(is_same<QuickSort<tuple<> >::type, tuple<>>::value, "");
  88. static_assert(is_same<QuickSort<tuple<i1>>::type, tuple<i1>>::value, "");
  89. static_assert(is_same<QuickSort<lst >::type, sorted_lst>::value, "");
  90. }