1 /* ///////////////////////////////////////////////////////////////////////
7 * Brief: Caculate P = sqrt<N> ==> N = P^2
10 * Copyright (c) 2008-2020, Waruqi All rights reserved.
11 * //////////////////////////////////////////////////////////////////// */
12 #ifndef EXTL_MPL_MATH_SQRT_H
13 #define EXTL_MPL_MATH_SQRT_H
16 * \brief Caculate P = sqrt<N> ==> N = P^2
18 #ifndef EXTL_MPL_MATH_SQRT_SUPPORT
19 # error extl::sqrt is not supported by current compiler.
22 /* ///////////////////////////////////////////////////////////////////////
28 #ifdef EXTL_MPL_IF_SUPPORT
32 /* ///////////////////////////////////////////////////////////////////////
33 * ::extl::mpl namespace
35 EXTL_MPL_BEGIN_WHOLE_NAMESPACE
37 /* ///////////////////////////////////////////////////////////////////////
40 #ifdef EXTL_MPL_SUPPORT
42 /* ///////////////////////////////////////////////////////////////////////
43 * Binary Search Method
45 * Fast, but prone to overflow
46 * //////////////////////////////////////////////////////////////////// */
47 #if defined(EXTL_TEMPLATE_PARTIAL_SPEC_SUPPORT) && \
48 !defined(EXTL_COMPILER_IS_DMC) && \
49 !defined(EXTL_COMPILER_IS_BORLAND)
50 /* //////////////////////////////////////////////////////////////////// */
51 EXTL_DETAIL_BEGIN_NAMESPACE
/* ::extl::mpl::detail namespace */
52 /* //////////////////////////////////////////////////////////////////// */
53 template < e_umax_int_t N
, e_umax_int_t L
= 0, e_umax_int_t H
= N
>
56 EXTL_STATIC_MEMBER_CONST(e_umax_int_t
, mid
= (L
+ H
+ 1) / 2);
58 /* In order to decrease the number of instaniation */
59 # ifdef EXTL_MPL_IF_SUPPORT
60 typedef typename_type_k if_
< (N
< (mid
* mid
))
61 , sqrt_impl
<N
, L
, (mid
- 1)>
62 , sqrt_impl
<N
, mid
, H
>
65 EXTL_STATIC_MEMBER_CONST(e_umax_int_t
, value
= result_t::value
);
67 EXTL_STATIC_MEMBER_CONST(e_umax_int_t
, value
= ((N
< (mid
* mid
))?
68 (sqrt_impl
<N
, L
, mid
- 1>::value
) : (sqrt_impl
<N
, mid
, H
>::value
)));
73 template < e_umax_int_t N
, e_umax_int_t R
>
74 struct sqrt_impl
<N
, R
, R
>
76 EXTL_STATIC_MEMBER_CONST(e_umax_int_t
, value
= R
);
78 /* //////////////////////////////////////////////////////////////////// */
79 EXTL_DETAIL_END_NAMESPACE
/* ::extl::mpl::detail namespace */
80 /* //////////////////////////////////////////////////////////////////// */
83 * \ingroup extl_group_mpl
85 template < e_umax_int_t N
>
87 : EXTL_NS_DETAIL(sqrt_impl
)<N
, 0, N
>
92 /* ///////////////////////////////////////////////////////////////////////
95 * Slow, but not easy to overflow
96 * //////////////////////////////////////////////////////////////////// */
97 EXTL_DETAIL_BEGIN_NAMESPACE
/* ::extl::mpl::detail namespace */
98 /* //////////////////////////////////////////////////////////////////// */
99 template < e_umax_int_t N
, e_umax_int_t I
= 0 >
102 /* In order to decrease the number of instaniation */
103 # ifdef EXTL_MPL_IF_SUPPORT
106 /*typedef typename_type_k if_< ((I * I) < N)
111 # ifdef EXTL_COMPILER_IS_BORLAND
112 typedef typename_type_k if_
< ((I
* I
) < N
)
114 , typename_type_k if_
< ((I
* I
) > N
)
120 typedef typename_type_k if_
< ((I
* I
) < N
)
122 , typename_type_k if_
< ((I
* I
) > N
)
123 , typename_type_k umax_int_
<I
>::prior
129 EXTL_STATIC_MEMBER_CONST(e_umax_int_t
, value
= result_t::value
);
132 /* Needs instaniation of all even if the result have been caculated */
133 /*template < e_umax_int_t N >
134 struct sqrt_impl<N, M>
136 EXTL_STATIC_MEMBER_CONST(e_umax_int_t, value = N);
138 /* EXTL_STATIC_MEMBER_CONST(e_umax_int_t, value = ((I * I) < N)?
139 (sqrt_impl<N, I+1>::value) : I)); */
142 /* //////////////////////////////////////////////////////////////////// */
143 EXTL_DETAIL_END_NAMESPACE
/* ::extl::mpl::detail namespace */
144 /* //////////////////////////////////////////////////////////////////// */
145 /*!\brief: sqrt class
147 * \ingroup extl_group_mpl
149 template < e_umax_int_t N
>
150 struct sqrt
: EXTL_NS_DETAIL(sqrt_impl
)<N
, 0>
153 #endif /* EXTL_TEMPLATE_PARTIAL_SPEC_SUPPORT */
155 /* ///////////////////////////////////////////////////////////////////////
158 #ifdef EXTL_MPL_MATH_SQRT_TEST_ENABLE
159 # include "unit_test/sqrt_test.h"
162 /* //////////////////////////////////////////////////////////////////// */
163 #endif /* EXTL_MPL_SUPPORT */
164 /* //////////////////////////////////////////////////////////////////// */
166 /* ///////////////////////////////////////////////////////////////////////
167 * ::extl::mpl namespace
169 EXTL_MPL_END_WHOLE_NAMESPACE
171 /* //////////////////////////////////////////////////////////////////// */
172 #endif /* EXTL_MPL_MATH_SQRT_H */
173 /* //////////////////////////////////////////////////////////////////// */