2 * compiletime_functions.hpp
5 * Created by Udi on 12/19/06.
8 #if !defined(_AKUPARA_COMPILETIME_FUNCTIONS_HPP__INCLUDED_)
9 #define _AKUPARA_COMPILETIME_FUNCTIONS_HPP__INCLUDED_
11 //#include "WavesPublicAPIs/wstdint.h"
15 // For templates that "return" a value, use template_name<arguments>::value
16 // For templates that "return" a type, use template_name<arguments>::type
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; };
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; };
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; };
37 struct compiletime_log2_floor<0> {}; // no value for 0 argument
38 //------------------------------------------------------------------------
42 // Assertion - accessing 'value' will generate a compile-time error if the argument evaluates to false
43 //------------------------------------------------------------------------
45 struct compiletime_assert;
48 struct compiletime_assert<true> { static const bool value=true; };
51 struct compiletime_assert<false> {}; // no value member for false assertion -> compile time error
52 //------------------------------------------------------------------------
55 // Select type - selects one of two types based on a boolean
56 //------------------------------------------------------------------------
57 template<bool, typename, typename>
58 struct compiletime_select_type;
60 template<typename _true_type, typename _false_type>
61 struct compiletime_select_type<true, _true_type, _false_type> { typedef _true_type type; };
63 template<typename _true_type, typename _false_type>
64 struct compiletime_select_type<false, _true_type, _false_type> { typedef _false_type type; };
65 //------------------------------------------------------------------------
71 // Integer types by byte count
72 //------------------------------------------------------------------------
75 template<unsigned int _size, bool _signed>
76 struct integer_with_byte_count_base;
79 struct integer_with_byte_count_base<1,true> { typedef int8_t type; };
82 struct integer_with_byte_count_base<2,true> { typedef int16_t type; };
85 struct integer_with_byte_count_base<4,true> { typedef int32_t type; };
88 struct integer_with_byte_count_base<8,true> { typedef int64_t type; };
91 struct integer_with_byte_count_base<1,false> { typedef uint8_t type; };
94 struct integer_with_byte_count_base<2,false> { typedef uint16_t type; };
97 struct integer_with_byte_count_base<4,false> { typedef uint32_t type; };
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>
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
109 //------------------------------------------------------------------------
110 template<unsigned int _size>
111 struct signed_integer_with_byte_count : public integer_with_byte_count<_size,true> {};
113 template<unsigned int _size>
114 struct unsigned_integer_with_byte_count : public integer_with_byte_count<_size,false> {};
115 //------------------------------------------------------------------------
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
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 //------------------------------------------------------------------------
137 // These are NOT TR1 but make use of some TR1 stuff
138 //------------------------------------------------------------------------
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 )
151 //AKUPARA_SIGNED_UNSIGNED_INTEGER_PAIR(4, int32_t )// 64BitConversion
154 signed_unsigned_pair<4>
156 typedef int32_t signed_type;
157 typedef uint32_t unsigned_type;
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;
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
171 // search for _T in signed type list
172 template<unsigned int _index, typename _T> struct find_in_signed_type_list_from_index
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;
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> {};
179 // search for _T in unsigned type list
180 template<unsigned int _index, typename _T> struct find_in_unsigned_type_list_from_index
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;
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> {};
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; };
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 //------------------------------------------------------------------------
203 } // namespace Akupara
205 #endif // _AKUPARA_COMPILETIME_FUNCTIONS_HPP__INCLUDED_