OpenWalnut  1.4.0
WCompileTimeFunctions.h
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #ifndef WCOMPILETIMEFUNCTIONS_H
00026 #define WCOMPILETIMEFUNCTIONS_H
00027 
00028 #include <string>
00029 
00030 /**
00031  * Implements compile-time evaluation of factorials.
00032  */
00033 template< std::size_t n >
00034 struct WFactorial
00035 {
00036     enum
00037     {
00038         value = n * WFactorial< n - 1 >::value
00039     };
00040 };
00041 
00042 /**
00043  * Specialization for n = 0.
00044  */
00045 template<>
00046 struct WFactorial< 0 >
00047 {
00048     enum
00049     {
00050         value = 1
00051     };
00052 };
00053 
00054 /**
00055  * Implements compile-time calculation of binomial coefficients.
00056  *
00057  *
00058  * WBinom< n, k >::value = n! / ( k!(n-k)! ).
00059  *
00060  * \note For k > n or n == k == 0, compilation fails.
00061  */
00062 template< std::size_t n, std::size_t k >
00063 struct WBinom
00064 {
00065     /**
00066      * Using an enum here instead of a static constant.
00067      */
00068     enum
00069     {
00070         /**
00071          * The computed value.
00072          */
00073         value = WBinom< n - 1, k - 1 >::value + WBinom< n - 1, k >::value
00074     };
00075 };
00076 
00077 /**
00078  * Specialization for n = k.
00079  */
00080 template< std::size_t n >
00081 struct WBinom< n, n >
00082 {
00083     /**
00084      * Using an enum here instead of a static constant.
00085      */
00086     enum
00087     {
00088         /**
00089          * The computed value.
00090          */
00091         value = 1
00092     };
00093 };
00094 
00095 /**
00096  * Specialization for k = 0.
00097  */
00098 template< std::size_t n >
00099 struct WBinom< n, 0 >
00100 {
00101     /**
00102      * Using an enum here instead of a static constant.
00103      */
00104     enum
00105     {
00106         /**
00107          * The computed value.
00108          */
00109         value = 1
00110     };
00111 };
00112 
00113 /**
00114  * This specialization of the WBinom struct is needed to avoid
00115  * infinite recursion in case of k > n. The compiler should abort
00116  * compilation with an error message.
00117  */
00118 template< std::size_t k >
00119 struct WBinom< 0, k >
00120 {
00121 };
00122 
00123 /**
00124  * Compute the nth power of a value.
00125  *
00126  * For base == exponent == 0, compilation fails.
00127  */
00128 template< std::size_t base, std::size_t exponent >
00129 struct WPower
00130 {
00131     /**
00132      * Using an enum here instead of a static constant.
00133      */
00134     enum
00135     {
00136         /**
00137          * The computed value.
00138          */
00139         value = base * WPower< base, exponent - 1 >::value
00140     };
00141 };
00142 
00143 /**
00144  * Compute the nth power of a value.
00145  *
00146  * Specialization for exponent = 0.
00147  */
00148 template< std::size_t base >
00149 struct WPower< base, 0 >
00150 {
00151     /**
00152      * Using an enum here instead of a static constant.
00153      */
00154     enum
00155     {
00156         /**
00157          * The computed value.
00158          */
00159         value = 1
00160     };
00161 };
00162 
00163 /**
00164  * Compute the nth power of a value.
00165  *
00166  * Specialization for exponent = 0.
00167  */
00168 template< std::size_t exponent >
00169 struct WPower< 0, exponent >
00170 {
00171     /**
00172      * Using an enum here instead of a static constant.
00173      */
00174     enum
00175     {
00176         /**
00177          * The computed value.
00178          */
00179         value = 0
00180     };
00181 };
00182 
00183 #endif  // WCOMPILETIMEFUNCTIONS_H