-
Notifications
You must be signed in to change notification settings - Fork 3
/
util.hpp
136 lines (105 loc) · 3.11 KB
/
util.hpp
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#ifndef _UTIL_HPP_
#define _UTIL_HPP_
/*
Function objects, FFT helpers, and utility functions for variadic templates.
Copyright Paul Keir 2012-2016
Distributed under the Boost Software License, Version 1.0.
(See accompanying file license.txt or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifdef CONSTMATH
#include "const_math.hpp"
#else
#include <cmath>
#endif
#include "mk_index_range.hpp"
template <typename ...Ts>
struct are_same;
template <typename T, typename ...Ts>
struct are_same<T,T,Ts...> {
static const bool value = true && are_same<T,Ts...>::value;
};
template <typename T>
struct are_same<T,T> {
static const bool value = true;
};
template <typename T, typename ...Ts>
struct pack_head {
typedef T type;
};
template <typename T>
struct Init {
constexpr Init(std::size_t n_) : n(n_) {}
constexpr T operator()(T y) const {
return 2 * M_PI / n * y;
}
std::size_t n;
};
template <typename T>
struct InitRofu {
constexpr InitRofu(std::size_t n_) : n(n_) {}
constexpr T operator()(std::size_t i) const {
return pow(exp(-2 * M_PI * T(0,1) / n),i);
}
std::size_t n;
};
template <typename T, typename U>
struct StaticCast {
constexpr T operator()(U u) const { return static_cast<T>(u); }
};
struct Succ {
constexpr int operator()(int x) const { return x+1; }
};
template <typename T>
struct Sum { // On the road to FoldR and FoldL ?
constexpr T operator()() const { return T(); }
template <typename ...Ts>
constexpr T operator()(T x, Ts ...xs) const { return x+operator()(xs...); }
};
template <typename T> constexpr T sum(T x, T y) { return x+y; } // concise
template <typename F, typename T>
struct FoldL {
constexpr FoldL(F f, T z) : m_f(f), m_z(z) {}
constexpr T operator()() const { return m_z; }
template <typename ...Ts>
constexpr
T operator()(T x, Ts ...xs) const { return m_f(x,operator()(xs...)); }
F m_f;
T m_z;
};
template <typename F, typename T>
constexpr
FoldL<F,T> make_foldl(F f, T z) { return FoldL<F,T>(f,z); }
template <typename T>
struct Sub {
constexpr T operator()(T x, T y) const { return x-y; }
};
template <typename T> constexpr T sub(T x, T y) { return x-y; } // concise
template <typename T>
struct Product {
constexpr T operator()(T x, T y) const { return x*y; }
};
template <typename T> constexpr T product(T x, T y) { return x*y; } // concise
template <typename T>
struct Id {
constexpr T operator()(T x) const { return x; }
};
template <typename Fa, typename Fb>
struct Comp {
Fa fa;
Fb fb;
constexpr Comp(Fa fa_, Fb fb_) : fa(fa_), fb(fb_) {}
template <typename ... Ts>
constexpr auto operator()(Ts ... ts) const -> decltype(fa(fb(ts...))) {
return fa(fb(ts...));
};
};
template <typename Fa, typename Fb>
constexpr
Comp<Fa,Fb> compose(Fa fa, Fb fb) { return Comp<Fa,Fb>(fa,fb); };
template <typename Fa, typename Fb, typename Fc, typename ... Fs>
constexpr
auto compose(Fa fa, Fb fb, Fc fc, Fs ... fs) ->
decltype(Comp<Fa,decltype(compose(fb,fc,fs...))>(fa,compose(fb,fc,fs...))) {
return Comp<Fa,decltype(compose(fb,fc,fs...))>(fa,compose(fb,fc,fs...));
};
#endif // _UTIL_HPP_