static_log2.hpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef BOOST_INTEGER_STATIC_LOG2_HPP
00017 #define BOOST_INTEGER_STATIC_LOG2_HPP
00018
00019 #include "boost/config.hpp"
00020
00021 namespace boost {
00022
00023 namespace detail {
00024
00025 namespace static_log2_impl {
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 typedef unsigned long argument_type;
00045 typedef int result_type;
00046
00047
00048 template <result_type n>
00049 struct choose_initial_n {
00050
00051 enum { c = (argument_type(1) << n << n) != 0 };
00052 BOOST_STATIC_CONSTANT(
00053 result_type,
00054 value = !c*n + choose_initial_n<2*c*n>::value
00055 );
00056
00057 };
00058
00059 template <>
00060 struct choose_initial_n<0> {
00061 BOOST_STATIC_CONSTANT(result_type, value = 0);
00062 };
00063
00064
00065
00066
00067 const result_type n_zero = 16;
00068 const result_type initial_n = choose_initial_n<n_zero>::value;
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 template <argument_type x, result_type n = initial_n>
00086 struct static_log2_impl {
00087
00088 enum { c = (x >> n) > 0 };
00089 BOOST_STATIC_CONSTANT(
00090 result_type,
00091 value = c*n + (static_log2_impl< (x>>c*n), n/2 >::value)
00092 );
00093
00094 };
00095
00096 template <>
00097 struct static_log2_impl<1, 0> {
00098 BOOST_STATIC_CONSTANT(result_type, value = 0);
00099 };
00100
00101 }
00102 }
00103
00104
00105
00106
00107
00108
00109
00110 typedef detail::static_log2_impl::argument_type static_log2_argument_type;
00111 typedef detail::static_log2_impl::result_type static_log2_result_type;
00112
00113
00114 template <static_log2_argument_type x>
00115 struct static_log2 {
00116
00117 BOOST_STATIC_CONSTANT(
00118 static_log2_result_type,
00119 value = detail::static_log2_impl::static_log2_impl<x>::value
00120 );
00121
00122 };
00123
00124
00125 template <>
00126 struct static_log2<0> { };
00127
00128 }
00129
00130
00131
00132 #endif // include guard