Skip to content

Instantly share code, notes, and snippets.

@jiripospisil
Created October 26, 2013 20:44
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jiripospisil/7174327 to your computer and use it in GitHub Desktop.
Save jiripospisil/7174327 to your computer and use it in GitHub Desktop.
So awesome!
// Author: Stephan T. Lavavej
// Code for "Stephan T. Lavavej - Core C++, 8 of n" from Channel 9 Videos
#include <iostream>
#include <array>
#include <climits>
using namespace std;
template<int... Vals>
struct Ints { };
/* Concat */
template<typename Ints1, typename Ints2>
struct Concat;
template<int... Vals1, int... Vals2>
struct Concat<Ints<Vals1...>, Ints<Vals2...>> {
typedef Ints<Vals1..., Vals2...> type;
};
/* BisectHelper */
template<typename Ints1, typename Ints2, bool Done>
struct BisectHelper;
template<int... Vals1, int... Vals2>
struct BisectHelper<Ints<Vals1...>, Ints<Vals2...>, true> {
typedef Ints<Vals1...> first;
typedef Ints<Vals2...> second;
};
template<int... Vals1, int X, int... Vals2>
struct BisectHelper<Ints<Vals1...>, Ints<X, Vals2...>, false>
: public BisectHelper<Ints<Vals1..., X>, Ints<Vals2...>, sizeof...(Vals2) + 1 >= sizeof...(Vals2)> { };
/* Bisect */
template<typename Ints1>
struct Bisect;
template<int... Vals>
struct Bisect<Ints<Vals...>>
: public BisectHelper<Ints<>, Ints<Vals...>, sizeof...(Vals) == 0> { };
/* Merge */
template<typename Ints1, typename Ints2>
struct Merge;
template<>
struct Merge<Ints<>, Ints<>> {
typedef Ints<> type;
};
template<int A, int... Vals1>
struct Merge<Ints<A, Vals1...>, Ints<>> {
typedef Ints<A, Vals1...> type;
};
template<int B, int... Vals2>
struct Merge<Ints<>, Ints<B, Vals2...>> {
typedef Ints<B, Vals2...> type;
};
/* MergeHelper */
template<bool TakeB, typename Ints1, typename Ints2>
struct MergeHelper;
/* Merge (cont) */
template<int A, int... Vals1, int B, int... Vals2>
struct Merge<Ints<A, Vals1...>, Ints<B, Vals2...>>
: MergeHelper<(B < A), Ints<A, Vals1...>, Ints<B, Vals2...>> { };
/* MergeHelper (cont) */
template<int A, int... Vals1, int B, int... Vals2>
struct MergeHelper<false, Ints<A, Vals1...>, Ints<B, Vals2...>>
: public Concat<Ints<A>, typename Merge<Ints<Vals1...>, Ints<B, Vals2...>>::type> { };
template<int A, int... Vals1, int B, int... Vals2>
struct MergeHelper<true, Ints<A, Vals1...>, Ints<B, Vals2...>>
: public Concat<Ints<B>, typename Merge<Ints<A, Vals1...>, Ints<Vals2...>>::type> { };
/* SortHelper */
template<typename Ints>
struct SortHelper;
template<>
struct SortHelper<Ints<>> {
typedef Ints<> type;
};
template<int A>
struct SortHelper<Ints<A>> {
typedef Ints<A> type;
};
template<int A, int B, int... Vals>
struct SortHelper<Ints<A, B, Vals...>> {
private:
typedef Bisect<Ints<A, B, Vals...>> bisect;
typedef typename bisect::first unsorted_first;
typedef typename bisect::second unsorted_second;
typedef typename SortHelper<unsorted_first>::type sorted_first;
typedef typename SortHelper<unsorted_second>::type sorted_second;
public:
typedef typename Merge<sorted_first, sorted_second>::type type;
};
/* Sort */
template<int... Vals>
struct Sort
: public SortHelper<Ints<Vals...>> { };
/* SortedArrayHelper */
template<typename Ints>
struct SortedArrayHelper;
template<int... Vals>
struct SortedArrayHelper<Ints<Vals...>> {
static const array<int, sizeof...(Vals)> arr;
};
template<int... Vals>
const array<int, sizeof...(Vals)> SortedArrayHelper<Ints<Vals...>>::arr = { { Vals... } };
/* SortedArray */
template<int... Vals>
struct SortedArray
: public SortedArrayHelper<typename Sort<Vals...>::type> { };
int main() {
typedef SortedArray<INT_MAX, 981, -2, 0, 12, -3, 1, 2, 82, 7, 5, INT_MIN> meow;
for (const auto& n : meow::arr) {
cout << n << " ";
}
cout << endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment