9c146dcebf62710f614b7fa4d48b303baaacab12
[ardour.git] / libs / backends / wavesaudio / wavesapi / akupara / compiletime_functions.hpp
1 /*
2 *  compiletime_functions.hpp
3 *  Akupara
4 *
5 *  Created by Udi on 12/19/06.
6 *
7 */
8 #if !defined(_AKUPARA_COMPILETIME_FUNCTIONS_HPP__INCLUDED_)
9 #define _AKUPARA_COMPILETIME_FUNCTIONS_HPP__INCLUDED_
10
11 //#include "WavesPublicAPIs/wstdint.h"
12
13 namespace Akupara
14 {
15     // For templates that "return" a value, use template_name<arguments>::value
16     // For templates that "return" a type, use template_name<arguments>::type
17
18
19     // Integer log2 functions
20     //------------------------------------------------------------------------
21     template<unsigned int n>
22     struct compiletime_bit_count_to_represent { static const unsigned int value = 1+compiletime_bit_count_to_represent<(n>>1)>::value; };
23
24     template<>
25     struct compiletime_bit_count_to_represent<0> { static const unsigned int value = 0; };
26     //------------------------------------------------------------------------
27     template<unsigned int n>
28     struct compiletime_log2_ceiling  { static const unsigned int value=compiletime_bit_count_to_represent<n-1>::value; };
29
30     template<>
31     struct compiletime_log2_ceiling<0> {}; // no value for 0 argument
32     //------------------------------------------------------------------------
33     template<unsigned int n>
34     struct compiletime_log2_floor { static const unsigned int value=compiletime_bit_count_to_represent<n>::value-1; };
35
36     template<>
37     struct compiletime_log2_floor<0> {}; // no value for 0 argument
38     //------------------------------------------------------------------------
39
40
41
42     // Assertion - accessing 'value' will generate a compile-time error if the argument evaluates to false
43     //------------------------------------------------------------------------
44     template<bool>
45     struct compiletime_assert;
46
47     template<>
48     struct compiletime_assert<true> { static const bool value=true; };
49
50     template<>
51     struct compiletime_assert<false> {}; // no value member for false assertion -> compile time error
52     //------------------------------------------------------------------------
53
54
55     // Select type - selects one of two types based on a boolean
56     //------------------------------------------------------------------------
57     template<bool, typename, typename>
58     struct compiletime_select_type;
59
60     template<typename _true_type, typename _false_type>
61     struct compiletime_select_type<true,  _true_type, _false_type> { typedef _true_type  type; };
62
63     template<typename _true_type, typename _false_type>
64     struct compiletime_select_type<false, _true_type, _false_type> { typedef _false_type type; };
65     //------------------------------------------------------------------------
66
67
68
69
70
71     // Integer types by byte count
72     //------------------------------------------------------------------------
73     namespace detail
74     {
75         template<unsigned int _size, bool _signed>
76         struct integer_with_byte_count_base;
77
78         template<>
79         struct integer_with_byte_count_base<1,true> { typedef int8_t  type; };
80
81         template<>
82         struct integer_with_byte_count_base<2,true> { typedef int16_t type; };
83
84         template<>
85         struct integer_with_byte_count_base<4,true> { typedef int32_t type; };
86
87         template<>
88         struct integer_with_byte_count_base<8,true> { typedef int64_t type; };
89
90         template<>
91         struct integer_with_byte_count_base<1,false> { typedef uint8_t  type; };
92
93         template<>
94         struct integer_with_byte_count_base<2,false> { typedef uint16_t type; };
95
96         template<>
97         struct integer_with_byte_count_base<4,false> { typedef uint32_t type; };
98
99         template<>
100         struct integer_with_byte_count_base<8,false> { typedef uint64_t type; };
101     } // namespace detail
102     //------------------------------------------------------------------------
103     template<unsigned int _size, bool _signed=true>
104     struct integer_with_byte_count : public detail::integer_with_byte_count_base<_size,_signed>
105     {
106         typedef typename detail::integer_with_byte_count_base<_size,_signed>::type type; // not required but makes the statement below less messy
107         static const bool s_correct_size = compiletime_assert<sizeof(type)==_size>::value;  // if you get a compilation error here then integer_with_byte_count is not defined correctly
108     };
109     //------------------------------------------------------------------------
110     template<unsigned int _size>
111     struct signed_integer_with_byte_count : public integer_with_byte_count<_size,true> {};
112
113     template<unsigned int _size>
114     struct unsigned_integer_with_byte_count : public integer_with_byte_count<_size,false> {};
115     //------------------------------------------------------------------------
116
117
118
119     // The following are TR1 compatible, until we get decent TR1 library support on all platforms
120     //------------------------------------------------------------------------
121     template<typename _T, _T _v>
122     struct integral_constant
123     {
124         static const _T                    value = _v;
125         typedef _T                         value_type;
126         typedef integral_constant<_T, _v>  type;
127     }; // struct integral_constant
128     typedef integral_constant<bool, false> false_type;
129     typedef integral_constant<bool, true > true_type;
130     //------------------------------------------------------------------------
131     template<typename _T, typename _U> struct is_same : public false_type {};
132     template<typename _T> struct is_same<_T,_T> : public true_type {};
133     //------------------------------------------------------------------------
134
135
136
137     // These are NOT TR1 but make use of some TR1 stuff
138     //------------------------------------------------------------------------
139     namespace detail
140     {
141         struct no_type;   // if you end up getting this type, it means that you asked for something that doesn't exist
142         template<unsigned int _pair_index> struct signed_unsigned_pair;
143 #define AKUPARA_SIGNED_UNSIGNED_INTEGER_PAIR(index, base_type_name) \
144     template<> struct signed_unsigned_pair<index> { typedef signed base_type_name signed_type; typedef unsigned base_type_name unsigned_type; };
145 #define AKUPARA_SIGNED_UNSIGNED_FLOAT_PAIR(index, type_name) \
146     template<> struct signed_unsigned_pair<index> { typedef type_name signed_type; typedef no_type unsigned_type; };
147         AKUPARA_SIGNED_UNSIGNED_INTEGER_PAIR(1, char     )
148             AKUPARA_SIGNED_UNSIGNED_INTEGER_PAIR(2, short    )
149             AKUPARA_SIGNED_UNSIGNED_INTEGER_PAIR(3, int      )
150                         
151                         //AKUPARA_SIGNED_UNSIGNED_INTEGER_PAIR(4, int32_t     )// 64BitConversion
152                         template<>
153                         struct
154                         signed_unsigned_pair<4>
155                         {
156                                 typedef int32_t signed_type;
157                                 typedef uint32_t  unsigned_type;
158                         };
159
160
161                         AKUPARA_SIGNED_UNSIGNED_INTEGER_PAIR(5, long long)
162             AKUPARA_SIGNED_UNSIGNED_FLOAT_PAIR  (6, float      )
163             AKUPARA_SIGNED_UNSIGNED_FLOAT_PAIR  (7, double     )
164             AKUPARA_SIGNED_UNSIGNED_FLOAT_PAIR  (8, long double)
165             const unsigned int k_signed_unsigned_pair_count = 8;
166
167         // eliminate the no_type type
168         template<typename _T> struct filtered_type { typedef _T type; };
169         template<> struct filtered_type<no_type> {}; // no type defined
170
171         // search for _T in signed type list
172         template<unsigned int _index, typename _T> struct find_in_signed_type_list_from_index
173         {
174             static const unsigned int value = is_same< _T, typename signed_unsigned_pair<_index>::signed_type >::value ? _index : find_in_signed_type_list_from_index<_index-1,_T>::value;
175         };
176         template<typename _T> struct find_in_signed_type_list_from_index<0, _T> { static const unsigned int value = 0; };
177         template<typename _T> struct find_in_signed_type_list : public find_in_signed_type_list_from_index<k_signed_unsigned_pair_count, _T> {};
178
179         // search for _T in unsigned type list
180         template<unsigned int _index, typename _T> struct find_in_unsigned_type_list_from_index
181         {
182             static const unsigned int value = is_same< _T, typename signed_unsigned_pair<_index>::unsigned_type >::value ? _index : find_in_unsigned_type_list_from_index<_index-1,_T>::value;
183         };
184         template<typename _T> struct find_in_unsigned_type_list_from_index<0, _T> { static const unsigned int value = 0; };
185         template<typename _T> struct find_in_unsigned_type_list : public find_in_unsigned_type_list_from_index<k_signed_unsigned_pair_count, _T> {};
186
187         template<bool _is_signed, bool _is_unsigned, typename _T> struct equivalent_signed_type;
188         template<typename _T> struct equivalent_signed_type  <true, false, _T> { typedef _T type; };
189         template<typename _T> struct equivalent_signed_type  <false, true, _T> { typedef typename filtered_type< typename signed_unsigned_pair< find_in_unsigned_type_list<_T>::value >::signed_type >::type type; };
190
191         template<bool _is_signed, bool _is_unsigned, typename _T> struct equivalent_unsigned_type;
192         template<typename _T> struct equivalent_unsigned_type<true, false, _T> { typedef typename filtered_type< typename signed_unsigned_pair< find_in_signed_type_list<_T>::value >::unsigned_type >::type type; };
193         template<typename _T> struct equivalent_unsigned_type<false, true, _T> { typedef _T type; };
194     } // namespace detail
195     //------------------------------------------------------------------------
196     template<typename _T> struct is_signed   { static const bool value = detail::find_in_signed_type_list  <_T>::value != 0; };
197     template<typename _T> struct is_unsigned { static const bool value = detail::find_in_unsigned_type_list<_T>::value != 0; };
198     //------------------------------------------------------------------------
199     template<typename _T> struct equivalent_signed_type   : public detail::equivalent_signed_type  < is_signed<_T>::value, is_unsigned<_T>::value, _T > {};
200     template<typename _T> struct equivalent_unsigned_type : public detail::equivalent_unsigned_type< is_signed<_T>::value, is_unsigned<_T>::value, _T > {};
201     //------------------------------------------------------------------------
202
203 } // namespace Akupara
204
205 #endif // _AKUPARA_COMPILETIME_FUNCTIONS_HPP__INCLUDED_