Alchemy  1.0 A framework to robustly process network messages and structured data
meta_math.h
1 /// @file meta/meta_math.h
2 ///
3 /// Math functions implemented in template meta-program style
4 /// that will be resolved at compile-time.
5 ///
7 /// @copyright 2014 Paul M Watt
8 // ****************************************************************************
9 #ifndef META_MATH_H_INCLUDED
10 #define META_MATH_H_INCLUDED
11 // Includes ******************************************************************
12 #include <Pb/meta_util.h>
13
14 namespace tmp
15 {
16
17 namespace math
18 {
19
20 // ***************************************************************************
21 /// Static calculation of power function.
22 ///
23 /// This is a collection of functions that provides that ability to calculate
24 /// the value of a number raised to an exponent. The calculation is performed
25 /// at compile-time, and the result can be used in further static calculations
26 /// and as template parameters.
27 ///
28 /// @param T [typename] The type to use as the result value.
29 /// @param var [T] A value of type T to act as the base of the value.
30 /// @param exp [unsigned char] The value of the exponent.
31 /// The max exponent can be number
32 ///
33 /// @note T must be an integral type otherwise the static const
34 /// initialization becomes illegal.
35 /// @note Supplying a exponent that is <= to the number of bits
36 /// in T will truncate the result.
37 ///
38 /// usage:
39 /// ~~~{.cpp}
40 /// // Calculate 10^3:
41 /// int result = tmp::math::pow<int, 10, 3>::value
42 ///
43 /// // Use the pow<> type to create a bit-mask constant:
44 /// // Use the pow<> type to create a bit-mask constant.
45 /// // The BitField Mask can be described with this formula:
46 /// // Mask = (2 ^ (number of bits))-1
47 /// // << shifted to the left by offset bits.
48 /// //
49 /// static const
50 /// size_t k_size = 3; ///< 3-bits in the mask
51 /// static const
52 /// size_t k_offset = 5; ///< Offset the mask 5-bits
53 ///
54 /// static const
55 /// T k_mask = T(((tmp::math::pow<T, 2, k_size>::value)-1) << k_offset);
56 ///
57 /// // k_mask is now equal to: 0xE0
58 /// // binary equivalent: 11100000
59 /// ~~~
60 ///
61 template<typename T, T var, unsigned char exp>
62 struct pow
63 {
64  static const T value = var * pow<T, var, exp-1>::value;
65 };
66
67 // ***************************************************************************
68 /// Static calculation of power function.
69 ///
70 template<typename T, T var>
71 struct pow<T, var, 1>
72 {
73  static const T value = var;
74 };
75
76 // ***************************************************************************
77 /// Static calculation of power function.
78 ///
79 template<typename T, T var>
80 struct pow<T, var, 0>
81 {
82  static const T value = 1;
83 };
84
85
86 // Template Meta implementation to accumulate values of indexed templates. ***
87
88 template< size_t index_t,
89  template<size_t> class T
90  >
91 struct accumulate_value
92 {
93  static const size_t value = T<index_t>::value
94  + accumulate_value<index_t-1,T>::value;
95 };
96
97 template<template<size_t> class T>
98 struct accumulate_value<0,T>
99 {
100  static const size_t value = T<0>::value;
101 };
102
103 } // namespace math
104
105 } // namespace tmp
106
107 #endif