From 652475bbbd203ab54b1f609bad5da397d69f97cc Mon Sep 17 00:00:00 2001 From: jwellbelove Date: Fri, 20 May 2016 13:54:33 +0100 Subject: [PATCH 1/3] Small improvement to etl::hash --- src/hash.h | 67 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 15 deletions(-) diff --git a/src/hash.h b/src/hash.h index a01bba8e..b4f511d5 100644 --- a/src/hash.h +++ b/src/hash.h @@ -36,6 +36,7 @@ SOFTWARE. // The default hash calculation. #include "fnv_1.h" #include "type_traits.h" +#include "static_assert.h" ///\defgroup hash Standard hash calculations ///\ingroup maths @@ -75,9 +76,11 @@ namespace etl /// Specialisation for bool. ///\ingroup hash //*************************************************************************** - template <> + template <> struct hash { + STATIC_ASSERT(sizeof(size_t) >= sizeof(bool)); + size_t operator ()(bool v) const { return static_cast(v); @@ -88,9 +91,11 @@ namespace etl /// Specialisation for char. ///\ingroup hash //*************************************************************************** - template <> + template <> struct hash { + STATIC_ASSERT(sizeof(size_t) >= sizeof(char)); + size_t operator ()(char v) const { return static_cast(v); @@ -104,6 +109,8 @@ namespace etl template<> struct hash { + STATIC_ASSERT(sizeof(size_t) >= sizeof(signed char)); + size_t operator ()(signed char v) const { return static_cast(v); @@ -117,6 +124,8 @@ namespace etl template<> struct hash { + STATIC_ASSERT(sizeof(size_t) >= sizeof(unsigned char)); + size_t operator ()(unsigned char v) const { return static_cast(v); @@ -130,6 +139,8 @@ namespace etl template<> struct hash { + STATIC_ASSERT(sizeof(size_t) >= sizeof(wchar_t)); + size_t operator ()(wchar_t v) const { return static_cast(v); @@ -140,9 +151,11 @@ namespace etl /// Specialisation for short. ///\ingroup hash //*************************************************************************** - template<> + template<> struct hash { + STATIC_ASSERT(sizeof(size_t) >= sizeof(short)); + size_t operator ()(short v) const { return static_cast(v); @@ -156,6 +169,8 @@ namespace etl template<> struct hash { + STATIC_ASSERT(sizeof(size_t) >= sizeof()); + size_t operator ()(unsigned short v) const { return static_cast(v); @@ -169,6 +184,8 @@ namespace etl template<> struct hash { + STATIC_ASSERT(sizeof(size_t) >= sizeofint()); + size_t operator ()(int v) const { return static_cast(v); @@ -179,9 +196,11 @@ namespace etl /// Specialisation for unsigned int. ///\ingroup hash //*************************************************************************** - template<> + template<> struct hash { + STATIC_ASSERT(sizeof(size_t) >= sizeof(unsigned int)); + size_t operator ()(unsigned int v) const { return static_cast(v); @@ -195,15 +214,17 @@ namespace etl template<> struct hash { + // If it fits into a size_t. template - typename etl::enable_if::type + typename etl::enable_if= sizeof(T), size_t>::type operator ()(T v) const { return static_cast(v); } + // If it doesn't fit into a size_t. template - typename etl::enable_if::type + typename etl::enable_if::type operator ()(T v) const { uint8_t* p = reinterpret_cast(&v); @@ -218,15 +239,17 @@ namespace etl template<> struct hash { + // If it fits into a size_t. template - typename etl::enable_if::type + typename etl::enable_if= sizeof(T), size_t>::type operator ()(T v) const { return static_cast(v); } + // If it doesn't fit into a size_t. template - typename etl::enable_if::type + typename etl::enable_if::type operator ()(T v) const { uint8_t* p = reinterpret_cast(&v); @@ -241,15 +264,17 @@ namespace etl template<> struct hash { + // If it fits into a size_t. template - typename etl::enable_if::type + typename etl::enable_if= sizeof(T), size_t>::type operator ()(T v) const { return static_cast(v); } + // If it doesn't fit into a size_t. template - typename etl::enable_if::type + typename etl::enable_if::type operator ()(T v) const { uint8_t* p = reinterpret_cast(&v); @@ -264,15 +289,17 @@ namespace etl template<> struct hash { + // If it fits into a size_t. template - typename etl::enable_if::type + typename etl::enable_if= sizeof(T), size_t>::type operator ()(T v) const { return static_cast(v); } + // If it doesn't fit into a size_t. template - typename etl::enable_if::type + typename etl::enable_if::type operator ()(T v) const { uint8_t* p = reinterpret_cast(&v); @@ -287,6 +314,7 @@ namespace etl template<> struct hash { + // If it's the same size as a size_t. template typename etl::enable_if::type operator ()(T v) const @@ -294,6 +322,7 @@ namespace etl return *reinterpret_cast(&v); } + // If it's not the same size as a size_t. template typename etl::enable_if::type operator ()(T v) const @@ -307,9 +336,10 @@ namespace etl /// Specialisation for double. ///\ingroup hash //*************************************************************************** - template<> + template<> struct hash { + // If it's the same size as a size_t. template typename etl::enable_if::type operator ()(T v) const @@ -317,6 +347,7 @@ namespace etl return *reinterpret_cast(&v); } + // If it's not the same size as a size_t. template typename etl::enable_if::type operator ()(T v) const @@ -330,9 +361,10 @@ namespace etl /// Specialisation for long double. ///\ingroup hash //*************************************************************************** - template<> + template<> struct hash { + // If it's the same size as a size_t. template typename etl::enable_if::type operator ()(T v) const @@ -340,6 +372,7 @@ namespace etl return *reinterpret_cast(&v); } + // If it's not the same size as a size_t. template typename etl::enable_if::type operator ()(T v) const @@ -353,9 +386,10 @@ namespace etl /// Specialisation for pointers. ///\ingroup hash //*************************************************************************** - template + template struct hash { + // If it's the same size as a size_t. template typename etl::enable_if::type operator ()(U* v) const @@ -363,6 +397,7 @@ namespace etl return reinterpret_cast(v); } + // If it's the same size as a size_t. template typename etl::enable_if::type operator ()(const U* v) const @@ -370,6 +405,7 @@ namespace etl return reinterpret_cast(v); } + // If it's not the same size as a size_t. template typename etl::enable_if::type operator ()(U* v) const @@ -378,6 +414,7 @@ namespace etl return __private_hash__::generic_hash(p, p + sizeof(v)); } + // If it's not the same size as a size_t. template typename etl::enable_if::type operator ()(const U* v) const From 4670262383e63ec89b88bae0c4c6912e1aeb7db7 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Fri, 20 May 2016 16:32:32 +0100 Subject: [PATCH 2/3] Improved debounce code. No functional change. --- src/debounce.h | 158 ++++++++++++++++++------------------------------- 1 file changed, 58 insertions(+), 100 deletions(-) diff --git a/src/debounce.h b/src/debounce.h index b0165c47..4416209c 100644 --- a/src/debounce.h +++ b/src/debounce.h @@ -119,7 +119,7 @@ namespace etl uint8_t state; /// The state count. - int16_t count; + uint16_t count; }; } @@ -170,13 +170,12 @@ namespace etl { debounce_base::add(sample); - if (sample) + if (count < REPEAT_THRESHOLD) { - // Set sample. - if (count < REPEAT_THRESHOLD) + ++count; + + if (sample) { - ++count; - if (count == VALID_THRESHOLD) { // Set. @@ -196,16 +195,12 @@ namespace etl state |= REPEATING; count = HOLD_THRESHOLD; } - } - } - else - { - // Clear sample. - if (count > -VALID_THRESHOLD) - { - --count; - if (count == -VALID_THRESHOLD) + state |= LAST; + } + else + { + if (count == VALID_THRESHOLD) { // Clear. state |= CHANGED; @@ -213,16 +208,9 @@ namespace etl state &= ~HELD; state &= ~REPEATING; } - } - } - if (sample) - { - state |= LAST; - } - else - { - state &= ~LAST; + state &= ~LAST; + } } return (state & CHANGED) != 0; @@ -266,13 +254,12 @@ namespace etl { debounce_base::add(sample); - if (sample) + if (count < HOLD_THRESHOLD) { - // Set sample. - if (count < HOLD_THRESHOLD) - { - ++count; + ++count; + if (sample) + { if (count == VALID_THRESHOLD) { // Set. @@ -285,32 +272,22 @@ namespace etl state |= CHANGED; state |= HELD; } - } - } - else - { - // Clear sample. - if (count > -VALID_THRESHOLD) - { - --count; - if (count == -VALID_THRESHOLD) + state |= LAST; + } + else + { + if (count == VALID_THRESHOLD) { // Clear. state |= CHANGED; state &= ~CURRENT; state &= ~HELD; + state &= ~REPEATING; } - } - } - if (sample) - { - state |= LAST; - } - else - { - state &= ~LAST; + state &= ~LAST; + } } return (state & CHANGED) != 0; @@ -352,44 +329,34 @@ namespace etl { debounce_base::add(sample); - if (sample) + if (count < VALID_THRESHOLD) { - // Set sample. - if (count < VALID_THRESHOLD) - { - ++count; + ++count; + if (sample) + { if (count == VALID_THRESHOLD) { // Set. state |= CHANGED; state |= CURRENT; } - } - } - else - { - // Clear sample. - if (count > -VALID_THRESHOLD) - { - --count; - if (count == -VALID_THRESHOLD) + state |= LAST; + } + else + { + if (count == VALID_THRESHOLD) { // Clear. state |= CHANGED; state &= ~CURRENT; + state &= ~HELD; + state &= ~REPEATING; } - } - } - if (sample) - { - state |= LAST; - } - else - { - state &= ~LAST; + state &= ~LAST; + } } return (state & CHANGED) != 0; @@ -453,33 +420,35 @@ namespace etl { debounce_base::add(sample); - if (sample) + if (count < repeat_threshold) { - // Set sample. - if (count < repeat_threshold) - { - ++count; + ++count; + if (sample) + { if (count == valid_threshold) { - // Set. - state |= CHANGED; - state |= CURRENT; + if (sample) + { + // Set. + state |= CHANGED; + state |= CURRENT; + } } - + if (hold_threshold != valid_threshold) { - if (count == hold_threshold) + if ((count == hold_threshold) && sample) { // Held. state |= CHANGED; state |= HELD; } } - + if (repeat_threshold != hold_threshold) { - if (count == repeat_threshold) + if ((count == repeat_threshold) && sample) { // Repeat. state |= CHANGED; @@ -487,16 +456,12 @@ namespace etl count = hold_threshold; } } - } - } - else - { - // Clear sample. - if (count > -valid_threshold) - { - --count; - if (count == -valid_threshold) + state |= LAST; + } + else + { + if (count == valid_threshold) { // Clear. state |= CHANGED; @@ -504,16 +469,9 @@ namespace etl state &= ~HELD; state &= ~REPEATING; } - } - } - if (sample) - { - state |= LAST; - } - else - { - state &= ~LAST; + state &= ~LAST; + } } return (state & CHANGED) != 0; From 9a1885ea299e462f76986ba12a9a86379e733031 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Fri, 20 May 2016 16:33:04 +0100 Subject: [PATCH 3/3] Modified hash templates. Added asserts. --- src/hash.h | 18 +++++++++--------- test/test_hash.cpp | 20 ++++++++++++++++++++ 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/hash.h b/src/hash.h index b4f511d5..1cb310df 100644 --- a/src/hash.h +++ b/src/hash.h @@ -79,7 +79,7 @@ namespace etl template <> struct hash { - STATIC_ASSERT(sizeof(size_t) >= sizeof(bool)); + STATIC_ASSERT(sizeof(size_t) >= sizeof(bool), "size_t smaller than type"); size_t operator ()(bool v) const { @@ -94,7 +94,7 @@ namespace etl template <> struct hash { - STATIC_ASSERT(sizeof(size_t) >= sizeof(char)); + STATIC_ASSERT(sizeof(size_t) >= sizeof(char), "size_t smaller than type"); size_t operator ()(char v) const { @@ -109,7 +109,7 @@ namespace etl template<> struct hash { - STATIC_ASSERT(sizeof(size_t) >= sizeof(signed char)); + STATIC_ASSERT(sizeof(size_t) >= sizeof(signed char), "size_t smaller than type"); size_t operator ()(signed char v) const { @@ -124,7 +124,7 @@ namespace etl template<> struct hash { - STATIC_ASSERT(sizeof(size_t) >= sizeof(unsigned char)); + STATIC_ASSERT(sizeof(size_t) >= sizeof(unsigned char), "size_t smaller than type"); size_t operator ()(unsigned char v) const { @@ -139,7 +139,7 @@ namespace etl template<> struct hash { - STATIC_ASSERT(sizeof(size_t) >= sizeof(wchar_t)); + STATIC_ASSERT(sizeof(size_t) >= sizeof(wchar_t), "size_t smaller than type"); size_t operator ()(wchar_t v) const { @@ -154,7 +154,7 @@ namespace etl template<> struct hash { - STATIC_ASSERT(sizeof(size_t) >= sizeof(short)); + STATIC_ASSERT(sizeof(size_t) >= sizeof(short), "size_t smaller than type"); size_t operator ()(short v) const { @@ -169,7 +169,7 @@ namespace etl template<> struct hash { - STATIC_ASSERT(sizeof(size_t) >= sizeof()); + STATIC_ASSERT(sizeof(size_t) >= sizeof(unsigned short), "size_t smaller than type"); size_t operator ()(unsigned short v) const { @@ -184,7 +184,7 @@ namespace etl template<> struct hash { - STATIC_ASSERT(sizeof(size_t) >= sizeofint()); + STATIC_ASSERT(sizeof(size_t) >= sizeof(int), "size_t smaller than type"); size_t operator ()(int v) const { @@ -199,7 +199,7 @@ namespace etl template<> struct hash { - STATIC_ASSERT(sizeof(size_t) >= sizeof(unsigned int)); + STATIC_ASSERT(sizeof(size_t) >= sizeof(unsigned int), "size_t smaller than type"); size_t operator ()(unsigned int v) const { diff --git a/test/test_hash.cpp b/test/test_hash.cpp index 79a9fe8a..53e50d70 100644 --- a/test/test_hash.cpp +++ b/test/test_hash.cpp @@ -170,6 +170,26 @@ namespace CHECK_EQUAL(size_t(&i), hash); } + + //************************************************************************* + TEST(test_hash_const_pointer) + { + int i; + size_t hash = etl::hash()(&i); + + CHECK_EQUAL(size_t(&i), hash); + } + + //************************************************************************* + TEST(test_hash_const_pointer_const) + { + int i; + const int * const pi = &i; + + size_t hash = etl::hash()(pi); + + CHECK_EQUAL(size_t(&i), hash); + } }; }