forked from altera-fpga/hls-samples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmetaprogramming_utils.hpp
140 lines (114 loc) · 3.85 KB
/
metaprogramming_utils.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
137
138
139
140
#ifndef __METAPROGRAMMING_UTILS_HPP__
#define __METAPROGRAMMING_UTILS_HPP__
#include <type_traits>
namespace fpga_tools {
//
// The code below creates the constexprs 'make_integer_range'
// and 'make_index_range' these are akin to 'std::make_integer_sequence'
// and 'std::make_index_sequence', respectively.
// However they allow you to specificy a range and can either increment
// or decrement, rather than a strict increasing sequence
//
template <typename T, typename, T begin, bool increase>
struct integer_range_impl;
// incrementing case
template <typename T, T... N, T begin>
struct integer_range_impl<T, std::integer_sequence<T, N...>, begin, true> {
using type = std::integer_sequence<T, N + begin...>;
};
// decrementing case
template <typename T, T... N, T begin>
struct integer_range_impl<T, std::integer_sequence<T, N...>, begin, false> {
using type = std::integer_sequence<T, begin - N...>;
};
// integer_range
template <typename T, T begin, T end>
using integer_range = typename integer_range_impl<
T, std::make_integer_sequence<T, (begin < end) ? end - begin : begin - end>,
begin, (begin < end)>::type;
//
// make_integer_range
//
// USAGE:
// make_integer_range<int,1,10>{} ==> 1,2,...,9
// make_integer_range<int,10,1>{} ==> 10,9,...,2
//
template <class T, T begin, T end>
using make_integer_range = integer_range<T, begin, end>;
//
// make_index_range
//
// USAGE:
// make_index_range<1,10>{} ==> 1,2,...,9
// make_index_range<10,1>{} ==> 10,9,...,2
//
template <std::size_t begin, std::size_t end>
using make_index_range = integer_range<std::size_t, begin, end>;
//
// The code below creates the constexprs 'make_integer_pow2_sequence'
// and 'make_index_pow2_sequence'. These generate the sequence
// 2^0, 2^1, 2^2, ... , 2^(N-1) = 1,2,4,...,2^(N-1)
//
template <typename T, typename>
struct integer_pow2_sequence_impl;
template <typename T, T... Pows>
struct integer_pow2_sequence_impl<T, std::integer_sequence<T, Pows...>> {
using type = std::integer_sequence<T, (T(1) << Pows)...>;
};
// integer_pow2_sequence
template <typename T, T N>
using integer_pow2_sequence =
typename integer_pow2_sequence_impl<T,
std::make_integer_sequence<T, N>>::type;
//
// make_integer_pow2_sequence
//
// USAGE:
// make_integer_pow2_sequence<int,5>{} ==> 1,2,4,8,16
//
template <class T, T N>
using make_integer_pow2_sequence = integer_pow2_sequence<T, N>;
//
// make_index_pow2_sequence
//
// USAGE:
// make_index_pow2_sequence<5>{} ==> 1,2,4,8,16
//
template <std::size_t N>
using make_index_pow2_sequence = integer_pow2_sequence<std::size_t, N>;
//
// Checks for existence of subscript operator
//
namespace detail {
template <typename... >
using void_t = void;
template<class T, typename = void>
struct has_subscript_impl : std::false_type { };
template<typename T>
struct has_subscript_impl<T, void_t<decltype(std::declval<T>()[1])>>
: std::true_type { };
} // namespace detail
template <typename T>
struct has_subscript {
static constexpr bool value =
std::is_same_v<typename detail::has_subscript_impl<T>::type, std::true_type>;
};
template <typename T>
inline constexpr bool has_subscript_v = has_subscript<T>::value;
//
// checks if a type is any instance of SYCL pipe
//
namespace detail {
template<typename T>
struct is_sycl_pipe_impl : std::false_type {};
template<typename Id, typename T, std::size_t N>
struct is_sycl_pipe_impl<sycl::ext::intel::pipe<Id, T, N>> : std::true_type {};
} // namespace detail
template <typename T>
struct is_sycl_pipe {
static constexpr bool value = detail::is_sycl_pipe_impl<T>{};
};
template <typename T>
inline constexpr bool is_sycl_pipe_v = is_sycl_pipe<T>::value;
} // namespace fpga_tools
#endif /* __METAPROGRAMMING_UTILS_HPP__ */