From 4cec2c88ffa110af5815b1620f2cca67780b4207 Mon Sep 17 00:00:00 2001 From: jwellbelove Date: Sat, 17 Jan 2015 14:01:06 +0000 Subject: [PATCH] Added more power templates Added power_of_2_round_up power_of_2_round_down is_power_of_2 --- power.h | 118 +++++++++++++++++++++++++++++++++++++++++++- test/test_maths.cpp | 100 +++++++++++++++++++++++++++++++++++++ 2 files changed, 217 insertions(+), 1 deletion(-) diff --git a/power.h b/power.h index 25e32c30..53c5bd2d 100644 --- a/power.h +++ b/power.h @@ -30,6 +30,7 @@ SOFTWARE. #define __ETL_POW__ #include +#include "log.h" ///\defgroup power power /// power : Calculates N to the power POWER. @@ -51,7 +52,8 @@ namespace etl }; //*************************************************************************** - // Specialisation for POWER == 0 + /// Calculates powers. + /// Specialisation for POWER == 0. //*************************************************************************** template struct power @@ -61,6 +63,120 @@ namespace etl value = 1 }; }; + + //*************************************************************************** + ///\ingroup power + /// Calculates the rounded up power of 2. + //*************************************************************************** + template + struct power_of_2_round_up + { + enum value_type + { + value = 1 << (etl::log2::value + 1) + }; + }; + + //*************************************************************************** + ///\ingroup power + /// Calculates the rounded up power of 2. + /// Specialisation for 0. + //*************************************************************************** + template <> + struct power_of_2_round_up<0> + { + enum value_type + { + value = 2 + }; + }; + + //*************************************************************************** + ///\ingroup power + /// Calculates the rounded down power of 2. + //*************************************************************************** + template + struct power_of_2_round_down + { + enum value_type + { + value = 1 << (etl::log2::value) + }; + }; + + //*************************************************************************** + ///\ingroup power + /// Calculates the rounded down power of 2. + /// Specialisation for 0. + //*************************************************************************** + template <> + struct power_of_2_round_down<0> + { + enum value_type + { + value = 2 + }; + }; + + //*************************************************************************** + ///\ingroup power + /// Calculates the rounded down power of 2. + /// Specialisation for 1. + //*************************************************************************** + template <> + struct power_of_2_round_down<1> + { + enum value_type + { + value = 2 + }; + }; + + //*************************************************************************** + ///\ingroup power + /// Calculates the rounded down power of 2. + /// Specialisation for 2. + //*************************************************************************** + template <> + struct power_of_2_round_down<2> + { + enum value_type + { + value = 2 + }; + }; + + //*************************************************************************** + ///\ingroup power + /// Checks if N is a power of 2. + //*************************************************************************** + template + struct is_power_of_2 + { + static const bool value = (N & (N - 1)) == 0; + }; + + //*************************************************************************** + ///\ingroup power + /// Checks if N is a power of 2. + /// Specialisation for 0. + //*************************************************************************** + template <> + struct is_power_of_2<0> + { + static const bool value = false; + }; + + //*************************************************************************** + ///\ingroup power + /// Checks if N is a power of 2. + /// Specialisation for 1. + //*************************************************************************** + template <> + struct is_power_of_2<1> + { + static const bool value = false; + }; } #endif diff --git a/test/test_maths.cpp b/test/test_maths.cpp index ddd9d704..d20c0ea0 100644 --- a/test/test_maths.cpp +++ b/test/test_maths.cpp @@ -164,6 +164,106 @@ namespace CHECK_EQUAL(1000000000, actual); } + //************************************************************************* + TEST(test_power_of_2_round_up) + { + int actual; + + // + actual = etl::power_of_2_round_up<0>::value; + CHECK_EQUAL(2, actual); + + actual = etl::power_of_2_round_up<1>::value; + CHECK_EQUAL(2, actual); + + actual = etl::power_of_2_round_up<2>::value; + CHECK_EQUAL(2, actual); + + actual = etl::power_of_2_round_up<3>::value; + CHECK_EQUAL(4, actual); + + actual = etl::power_of_2_round_up<4>::value; + CHECK_EQUAL(4, actual); + + actual = etl::power_of_2_round_up<5>::value; + CHECK_EQUAL(8, actual); + + actual = etl::power_of_2_round_up<127>::value; + CHECK_EQUAL(128, actual); + + actual = etl::power_of_2_round_up<128>::value; + CHECK_EQUAL(128, actual); + + actual = etl::power_of_2_round_up<129>::value; + CHECK_EQUAL(256, actual); + } + + //************************************************************************* + TEST(test_power_of_2_round_down) + { + int actual; + + actual = etl::power_of_2_round_down<0>::value; + CHECK_EQUAL(2, actual); + + actual = etl::power_of_2_round_down<1>::value; + CHECK_EQUAL(2, actual); + + actual = etl::power_of_2_round_down<2>::value; + CHECK_EQUAL(2, actual); + + actual = etl::power_of_2_round_down<3>::value; + CHECK_EQUAL(2, actual); + + actual = etl::power_of_2_round_down<4>::value; + CHECK_EQUAL(2, actual); + + actual = etl::power_of_2_round_down<5>::value; + CHECK_EQUAL(4, actual); + + actual = etl::power_of_2_round_down<127>::value; + CHECK_EQUAL(64, actual); + + actual = etl::power_of_2_round_down<128>::value; + CHECK_EQUAL(64, actual); + + actual = etl::power_of_2_round_down<129>::value; + CHECK_EQUAL(128, actual); + } + + //************************************************************************* + TEST(test_is_power_of_2) + { + bool actual; + + actual = etl::is_power_of_2<0>::value; + CHECK_EQUAL(false, actual); + + actual = etl::is_power_of_2<1>::value; + CHECK_EQUAL(false, actual); + + actual = etl::is_power_of_2<2>::value; + CHECK_EQUAL(true, actual); + + actual = etl::is_power_of_2<3>::value; + CHECK_EQUAL(false, actual); + + actual = etl::is_power_of_2<4>::value; + CHECK_EQUAL(true, actual); + + actual = etl::is_power_of_2<5>::value; + CHECK_EQUAL(false, actual); + + actual = etl::is_power_of_2<127>::value; + CHECK_EQUAL(false, actual); + + actual = etl::is_power_of_2<128>::value; + CHECK_EQUAL(true, actual); + + actual = etl::is_power_of_2<129>::value; + CHECK_EQUAL(false, actual); + } + //************************************************************************* TEST(test_fibbonacci) {