00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef MLN_METAL_MATH_SQRT_HH
00027 # define MLN_METAL_MATH_SQRT_HH
00028
00036 # include <mln/metal/bool.hh>
00037 # include <mln/metal/int.hh>
00038
00039
00040 # define mlc_sqrt_int(N) mln::metal::math::sqrt_int<( N )>::value
00041
00042
00043 namespace mln
00044 {
00045
00046 namespace metal
00047 {
00048
00049 namespace math
00050 {
00051
00052
00053
00054 namespace impl
00055 {
00056
00057 template <int n, int lo = 1, int hi = n>
00058 struct sqrt_int_
00059 {
00060 enum {
00061 mid = (lo + hi + 1) / 2,
00062 val_lo = sqrt_int_<n, lo, mid-1>::value,
00063 val_hi = sqrt_int_<n, mid, hi>::value
00064 };
00065 enum { value = n < mid * mid ? val_lo : val_hi };
00066 };
00067
00068 template<int n, int m>
00069 struct sqrt_int_<n, m, m>
00070 {
00071 enum { value = m };
00072 };
00073
00074
00075
00076 template <int n, bool b>
00077 struct sqrt_int_if_ : sqrt_int_<n>
00078 {
00079 enum { value_ = sqrt_int_<n>::value,
00080 reminder_ = n - value_ * value_ };
00081
00082 };
00083
00084 template <int n>
00085 struct sqrt_int_if_< n, false >
00086 {
00087 };
00088
00089 }
00090
00091 template <int n>
00092 struct sqrt_int : impl::sqrt_int_if_< n, (n >= 0) >
00093 {
00094 };
00095
00096
00097
00098
00099 template <typename N>
00100 struct sqrt;
00101
00102 template <int n>
00103 struct sqrt< int_<n> >
00104 {
00105 typedef int_< sqrt_int<n>::value > ret;
00106 };
00107
00108
00109 }
00110
00111 }
00112
00113 }
00114
00115
00116 #endif // ! MLN_METAL_MATH_SQRT_HH