-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmerge_sorted_sets.h
110 lines (104 loc) · 2.54 KB
/
merge_sorted_sets.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#pragma once
#include <boost/mp11.hpp>
#include <type_traits>
#include <utility>
namespace taylor
{
namespace implementation
{
//namespace mp = boost::mp11;
using namespace boost::mp11;
template<typename A, typename B>
struct pair
{ typedef A first_type;
typedef B second_type;
};
template<typename PAIR>
using first_of_pair = typename PAIR::first_type;
template<typename PAIR>
using second_of_pair = typename PAIR::second_type;
template<typename, typename>
struct combineTwo;
template<typename A>
struct combineTwo<A, A>
{ typedef A type;
};
template<template<typename, typename> class F, typename Set1, typename Set2, template<typename, typename> class MERGE=combineTwo>
struct merge_sorted_sets;
template<template<typename, typename> class F, template<typename, typename> class MERGE>
struct merge_sorted_sets<F, mp_list<>, mp_list<>, MERGE>
{ using type = mp_list<>;
};
template<template<typename, typename> class F, typename ...T, template<typename, typename> class MERGE>
struct merge_sorted_sets<F, mp_list<T...>, mp_list<T...>, MERGE>
{ using type = mp_list<T...>;
};
template<template<typename, typename> class F, typename... Ts, template<typename, typename> class MERGE>
struct merge_sorted_sets<F, mp_list<Ts...>, mp_list<>, MERGE>
{ using type = mp_list<Ts...>;
};
template<template<typename, typename> class F, typename... Ts, template<typename, typename> class MERGE>
struct merge_sorted_sets<F, mp_list<>, mp_list<Ts...>, MERGE>
{ using type = mp_list<Ts...>;
};
template<template<typename, typename> class F, typename... Ts1, typename... Ts2, template<typename, typename> class MERGE>
struct merge_sorted_sets<F, mp_list<Ts1...>, mp_list<Ts2...>, MERGE>
{ typedef mp_list<Ts1...> TS1;
typedef mp_list<Ts2...> TS2;
typedef mp_front<TS1> T1;
typedef mp_front<TS2> T2;
struct defer_true
{ typedef pair<
merge_sorted_sets<
F,
mp_pop_front<TS1>,
TS2,
MERGE
>,
mp_identity<T1>
> type;
};
struct defer_false
{ typedef mp_if<
typename F<T2, T1>::type,
pair<
merge_sorted_sets<
F,
TS1,
mp_pop_front<TS2>,
MERGE
>,
mp_identity<T2>
>,
pair<
merge_sorted_sets<
F,
mp_pop_front<TS1>,
mp_pop_front<TS2>,
MERGE
>,
MERGE<
mp_front<
TS2
>,
mp_front<
TS1
>
>
>
> type;
};
typedef typename mp_if<
typename F<T1, T2>::type,
defer_true,
defer_false
>::type tmp;
using type = mp_push_front<
typename tmp::first_type::type,
typename tmp::second_type::type
>;
};
}
using implementation::merge_sorted_sets;
using implementation::pair;
}