-
Notifications
You must be signed in to change notification settings - Fork 0
/
utility_valuetable.hpp
98 lines (79 loc) · 2.93 KB
/
utility_valuetable.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
#ifndef SCHLAZICONTROL_UTILITY_VALUETABLE_HPP
#define SCHLAZICONTROL_UTILITY_VALUETABLE_HPP
#include <cstdlib>
#include <limits>
namespace sc {
namespace detail {
template< typename R, typename I >
struct ValueTable_function_traits
{
typedef R result_type;
typedef I input_type;
};
template< typename R, typename I >
ValueTable_function_traits< R, I > get_ValueTable_function_traits( R ( *func )( I ) );
template< typename F >
struct ValueTable_traits
{
typedef decltype( get_ValueTable_function_traits( &F::apply ) ) function_traits;
typedef typename function_traits::result_type result_type;
typedef typename function_traits::input_type input_type;
};
template<
typename F,
typename ValueTable_traits< F >::input_type I,
typename ValueTable_traits< F >::input_type To,
typename ValueTable_traits< F >::result_type... Values
>
struct ValueTable_values
{
typedef ValueTable_traits< F > traits_type;
typedef typename traits_type::result_type result_type;
typedef typename traits_type::input_type input_type;
typedef ValueTable_values< F, I + 1, To, Values..., F::apply( I ) > next_type;
static decltype( next_type::values ) constexpr& values = next_type::values;
};
template<
typename F,
typename ValueTable_traits< F >::input_type I,
typename ValueTable_traits< F >::input_type To,
typename ValueTable_traits< F >::result_type... Values
>
decltype( ValueTable_values< F, I, To, Values... >::next_type::values ) constexpr& ValueTable_values< F, I, To, Values... >::values;
template<
typename F,
typename ValueTable_traits< F >::input_type To,
typename ValueTable_traits< F >::result_type... Values
>
struct ValueTable_values< F, To, To, Values... >
{
typedef ValueTable_traits< F > traits_type;
typedef typename traits_type::result_type result_type;
static result_type constexpr const values[] { Values..., F::apply( To ) };
};
template<
typename F,
typename ValueTable_traits< F >::input_type To,
typename ValueTable_traits< F >::result_type... Values
>
typename ValueTable_traits< F >::result_type constexpr const ValueTable_values< F, To, To, Values... >::values[];
} // namespace detail
template<
typename F,
typename detail::ValueTable_traits< F >::input_type From = std::numeric_limits< typename detail::ValueTable_traits< F >::input_type >::min(),
typename detail::ValueTable_traits< F >::input_type To = std::numeric_limits< typename detail::ValueTable_traits< F >::input_type >::max()
>
class ValueTable
{
typedef detail::ValueTable_traits< F > traits_type;
typedef typename traits_type::result_type result_type;
typedef typename traits_type::input_type input_type;
typedef detail::ValueTable_values< F, From, To > values_type;
public:
static result_type constexpr get( input_type input )
{
return values_type::values[ input - From ];
}
};
} // namespace sc
#endif // SCHLAZICONTROL_UTILITY_VALUETABLE_HPP