Skip to content

Instantly share code, notes, and snippets.

@KPCCoiL
Last active August 29, 2015 14:19
Show Gist options
  • Save KPCCoiL/3fdcd063b3c14e804f33 to your computer and use it in GitHub Desktop.
Save KPCCoiL/3fdcd063b3c14e804f33 to your computer and use it in GitHub Desktop.
Pairing heap in TMP
//Pairing heap implementation in TMP
#include <iostream>
#include <type_traits>
#include <tuple>
using std::tuple;
struct Empty;
template <int, class>
struct Node;
template <class>
struct is_heap : std::false_type {};
template <>
struct is_heap<Empty> : std::true_type {};
template <int N, class... Children>
struct is_heap<Node<N, tuple<Children...>>> : std::true_type {};
template <class, class>
struct merge;
template <class T>
struct merge <Empty, T>
: std::enable_if<is_heap<T>::value, T> {};
template <class T>
struct merge <T, Empty>
: std::enable_if<is_heap<T>::value, T> {};
template <int X, int Y, class... Xs, class... Ys>
struct merge <Node<X, tuple<Xs...>>, Node<Y, tuple<Ys...>>>
: std::conditional <
(X < Y),
Node<X, tuple<Node<Y, tuple<Ys...>>, Xs...>>,
Node<Y, tuple<Node<X, tuple<Xs...>>, Ys...>>> {};
template <class>
struct merge_tuple
;
template <>
struct merge_tuple<tuple<>> {
using type = Empty;
};
template <class X>
struct merge_tuple<tuple<X>> {
using type = X;
};
template <class X, class Y, class... Rest>
struct merge_tuple<tuple<X, Y, Rest...>> {
using type = typename merge <
typename merge<X, Y>::type,
typename merge_tuple<tuple<Rest...>>::type>::type;
};
template <int X, class Heap>
struct push {
using type = typename merge<Node<X, tuple<>>, Heap>::type;
};
template <class>
struct pop;
template <int X, class... Xs>
struct pop<Node<X, tuple<Xs...>>> {
using type = typename merge_tuple<tuple<Xs...>>::type;
};
template <class>
struct top;
template <int X, class... Xs>
struct top<Node<X, tuple<Xs...>>>
: std::integral_constant<int, X> {};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment