瀏覽代碼

Added quicksort as candidate sample to code list.

Ye WU 8 年之前
父節點
當前提交
6ae5101907
共有 1 個文件被更改,包括 104 次插入0 次删除
  1. 104 0
      QuickSort.cpp

+ 104 - 0
QuickSort.cpp

@@ -0,0 +1,104 @@
+#include <tuple>
+#include <type_traits>
+#include <iostream>
+
+using std::tuple;
+using std::integral_constant;
+using std::is_same;
+
+template <int... values> struct to_int_types{
+	typedef tuple< integral_constant<int, values>... > type;
+};
+
+template <typename Pivot> struct Less {
+	template <typename X> struct Apply {
+		static bool const value = X::value < Pivot::value;
+	};
+};
+
+template <typename Pivot> struct GE {
+	template <typename X> struct Apply {
+		static bool const value = X::value >= Pivot::value;
+	};
+};
+
+template <typename x, bool realAdd, typename tuple>         struct Tuple_PushFront {};
+template <typename x, typename... tupleElems> struct Tuple_PushFront<x, true, tuple<tupleElems...>> {
+	typedef tuple<x, tupleElems...> type;
+};
+template <typename x, typename... tupleElems> struct Tuple_PushFront<x, false, tuple<tupleElems...>> {
+	typedef tuple<tupleElems...> type;
+};
+
+template <typename Pred, typename tuple> struct Filter;
+template <typename Pred> struct Filter< Pred, tuple<> > {
+	typedef tuple<> type;
+};
+template <typename Pred, typename Head, typename... Ts> struct Filter< Pred, tuple<Head, Ts...> > {
+	typedef typename Tuple_PushFront<
+		Head, Pred::template Apply<Head>::value, typename Filter<Pred, tuple<Ts...>>::type
+	>::type type;
+};
+
+template <typename... Tuples> struct ConcatenateTuple {};
+template <typename    Tuple0> struct ConcatenateTuple<Tuple0> {
+	typedef Tuple0 type;
+};
+
+template <typename Tuple0, typename Tuple1> struct ConcatenateTuple<Tuple0, Tuple1> {
+	template <typename TupleA> struct ConcatenateImpl {};
+	template <typename... TAs> struct ConcatenateImpl< tuple<TAs...> > {
+		template <typename TupleB> struct Apply;
+		template <typename... TBs> struct Apply< tuple<TBs...> > {
+			typedef tuple<TAs..., TBs...> type;
+		};
+	};
+	typedef typename ConcatenateImpl<Tuple0>::template Apply<Tuple1>::type type;
+};
+template <typename FirstTuple, typename... Follows> struct ConcatenateTuple<FirstTuple, Follows...> {
+	typedef typename ConcatenateTuple<
+		FirstTuple, typename ConcatenateTuple<Follows...>::type
+	>::type type;
+};
+
+template <typename tuple> struct QuickSort {};
+template <>               struct QuickSort< tuple<  > > { typedef tuple<  > type; };
+template <typename T0>    struct QuickSort< tuple<T0> > { typedef tuple<T0> type; };
+template <typename Head, typename... Ts>
+struct QuickSort< tuple<Head, Ts...> > {
+	typedef typename Filter< Less<Head>, tuple<Ts...> >::type LeftElems;
+	typedef typename Filter< GE  <Head>, tuple<Ts...> >::type RightElems;
+	typedef typename ConcatenateTuple<
+		typename QuickSort<LeftElems>::type, tuple<Head>, typename QuickSort<RightElems>::type
+	>::type type;
+};
+
+void StaticTest()
+{
+	typedef to_int_types<1, 2, 3>::type lst_1_3;
+	typedef to_int_types<3, 2, 1>::type lst_3_1;
+	typedef to_int_types<3, 7, 1, 6, 5, 22, 5>::type lst;
+
+	typedef integral_constant<int, 1>::type i1;
+	typedef integral_constant<int, 2>::type i2;
+	typedef integral_constant<int, 3>::type i3;
+
+	static_assert(Less<i2>::Apply<i1>::value == true, "");
+	static_assert(Less<i1>::Apply<i1>::value == false, "");
+	static_assert(Less<i1>::Apply<i2>::value == false, "");
+
+	static_assert(GE<i2>::Apply<i3>::value == true, "");
+	static_assert(GE<i2>::Apply<i2>::value == true, "");
+	static_assert(GE<i3>::Apply<i2>::value == false, "");
+
+	static_assert(is_same<Tuple_PushFront<i1, true,  tuple<i2>>::type, tuple<i1, i2>>::value, "");
+	static_assert(is_same<Tuple_PushFront<i2, true,  tuple<i1>>::type, tuple<i2, i1>>::value, "");
+	static_assert(is_same<Tuple_PushFront<i2, false, tuple<i1>>::type, tuple<i1>>::value,     "");
+
+	static_assert(is_same<Filter<Less<i2>, lst_1_3>::type, tuple<i1>>::value, "");
+
+	static_assert(is_same<QuickSort<lst_1_3  >::type, lst_1_3>::value, "");
+	static_assert(is_same<QuickSort<lst_3_1  >::type, lst_1_3>::value, "");
+	static_assert(is_same<QuickSort<tuple<>  >::type, tuple<>>::value, "");
+	static_assert(is_same<QuickSort<tuple<i1>>::type, tuple<i1>>::value, "");
+}