From 566cc682c3ed3ca439845c83e31a7ad995cc024c Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 18:40:46 +0100 Subject: [PATCH 01/34] Fixed 32/64 bit warning --- src/binary.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/binary.h b/src/binary.h index 81cf100c..a1aebdc7 100644 --- a/src/binary.h +++ b/src/binary.h @@ -543,7 +543,7 @@ namespace etl typedef typename etl::make_unsigned::type mask_t; - mask_t negative = (1 << (NBITS - 1)); + mask_t negative = (TReturn(1) << (NBITS - 1)); TReturn signed_value = value; if ((signed_value & negative) != 0) From 15958f9d650bb7ed1a2ff5e2e7f117cf618053bf Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 18:45:21 +0100 Subject: [PATCH 02/34] Simplfied default hash definitions. --- src/bloom_filter.h | 104 +++++++++++++++++++++++++++------------------ 1 file changed, 63 insertions(+), 41 deletions(-) diff --git a/src/bloom_filter.h b/src/bloom_filter.h index 3407d6e6..dfccf9f3 100644 --- a/src/bloom_filter.h +++ b/src/bloom_filter.h @@ -44,40 +44,26 @@ SOFTWARE. namespace etl { - namespace __private_bloom_filter__ - { - // Placeholder null hash for defaulted template parameters. - struct null_hash - { - template - size_t operator ()(T) - { - return 0; - } - }; - } - //*************************************************************************** /// An implementation of a bloom filter. /// Allows up to three hashes to be defined. /// Hashes must support the () operator and define 'argument_type'. ///\tparam DESIRED_WIDTH The desired number of hash results that can be stored. Rounded up to best fit the underlying bitset. ///\tparam THash1 The first hash generator class. - ///\tparam THash2 The second hash generator class. If omitted, uses the null hash. - ///\tparam THash3 The third hash generator class. If omitted, uses the null hash. + ///\tparam THash2 The second hash generator class. Default unused. + ///\tparam THash3 The third hash generator class. Default unused. /// The hash classes must define argument_type. ///\ingroup bloom_filter //*************************************************************************** template + typename THash2 = void, + typename THash3 = void> class bloom_filter { private: typedef typename etl::parameter_type::type parameter_t; - typedef __private_bloom_filter__::null_hash null_hash; public: @@ -99,19 +85,36 @@ namespace etl /// Adds a key to the filter. ///\param key The key to add. //*************************************************************************** - void add(parameter_t key) + template + typename etl::enable_if::value && etl::is_same::value, void>::type + add(parameter_t key) { flags.set(get_hash(key)); + } - if (!etl::is_same::value) - { - flags.set(get_hash(key)); - } - - if (!etl::is_same::value) - { - flags.set(get_hash(key)); - } + //*************************************************************************** + /// Adds a key to the filter. + ///\param key The key to add. + //*************************************************************************** + template + typename etl::enable_if::value && etl::is_same::value, void>::type + add(parameter_t key) + { + flags.set(get_hash(key)); + flags.set(get_hash(key)); + } + + //*************************************************************************** + /// Adds a key to the filter. + ///\param key The key to add. + //*************************************************************************** + template + typename etl::enable_if::value && !etl::is_same::value, void>::type + add(parameter_t key) + { + flags.set(get_hash(key)); + flags.set(get_hash(key)); + flags.set(get_hash(key)); } //*************************************************************************** @@ -119,23 +122,42 @@ namespace etl ///\param key The key to test. ///\return true if the key exists in the filter. //*************************************************************************** - bool exists(parameter_t key) const + template + typename etl::enable_if::value && etl::is_same::value, bool>::type + exists(parameter_t key) const { bool exists1 = flags[get_hash(key)]; - bool exists2 = true; - bool exists3 = true; - // Do we have a second hash? - if (!etl::is_same::value) - { - exists2 = flags[get_hash(key)]; - } + return exists1; + } - // Do we have a third hash? - if (!etl::is_same::value) - { - exists3 = flags[get_hash(key)]; - } + //*************************************************************************** + /// Tests a key to see if it exists in the filter. + ///\param key The key to test. + ///\return true if the key exists in the filter. + //*************************************************************************** + template + typename etl::enable_if::value && etl::is_same::value, bool>::type + exists(parameter_t key) const + { + bool exists1 = flags[get_hash(key)]; + bool exists2 = flags[get_hash(key)]; + + return exists1 && exists2; + } + + //*************************************************************************** + /// Tests a key to see if it exists in the filter. + ///\param key The key to test. + ///\return true if the key exists in the filter. + //*************************************************************************** + template + typename etl::enable_if::value && !etl::is_same::value, bool>::type + exists(parameter_t key) const + { + bool exists1 = flags[get_hash(key)]; + bool exists2 = flags[get_hash(key)]; + bool exists3 = flags[get_hash(key)]; return exists1 && exists2 && exists3; } From 8754ff7feb2b8200ae815df3c108ab10e1446ede Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 18:46:12 +0100 Subject: [PATCH 03/34] Used enable_if to optimise hash classes. --- src/hash.h | 184 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 103 insertions(+), 81 deletions(-) diff --git a/src/hash.h b/src/hash.h index 417f68dd..a01bba8e 100644 --- a/src/hash.h +++ b/src/hash.h @@ -35,7 +35,6 @@ SOFTWARE. // The default hash calculation. #include "fnv_1.h" - #include "type_traits.h" ///\defgroup hash Standard hash calculations @@ -196,18 +195,19 @@ namespace etl template<> struct hash { - size_t operator ()(long v) const + template + typename etl::enable_if::type + operator ()(T v) const { - if (sizeof(size_t) == sizeof(v)) - { - return static_cast(v); - } - else - { - uint8_t* p = reinterpret_cast(&v); + return static_cast(v); + } - return __private_hash__::generic_hash(p, p + sizeof(v)); - } + template + typename etl::enable_if::type + operator ()(T v) const + { + uint8_t* p = reinterpret_cast(&v); + return __private_hash__::generic_hash(p, p + sizeof(v)); } }; @@ -218,18 +218,19 @@ namespace etl template<> struct hash { - size_t operator ()(long long v) const + template + typename etl::enable_if::type + operator ()(T v) const { - if (sizeof(size_t) == sizeof(v)) - { - return static_cast(v); - } - else - { - uint8_t* p = reinterpret_cast(&v); + return static_cast(v); + } - return __private_hash__::generic_hash(p, p + sizeof(v)); - } + template + typename etl::enable_if::type + operator ()(T v) const + { + uint8_t* p = reinterpret_cast(&v); + return __private_hash__::generic_hash(p, p + sizeof(v)); } }; @@ -240,18 +241,19 @@ namespace etl template<> struct hash { - size_t operator ()(unsigned long v) const + template + typename etl::enable_if::type + operator ()(T v) const { - if (sizeof(size_t) == sizeof(v)) - { - return static_cast(v); - } - else - { - uint8_t* p = reinterpret_cast(&v); + return static_cast(v); + } - return __private_hash__::generic_hash(p, p + sizeof(v)); - } + template + typename etl::enable_if::type + operator ()(T v) const + { + uint8_t* p = reinterpret_cast(&v); + return __private_hash__::generic_hash(p, p + sizeof(v)); } }; @@ -262,18 +264,19 @@ namespace etl template<> struct hash { - size_t operator ()(unsigned long long v) const + template + typename etl::enable_if::type + operator ()(T v) const { - if (sizeof(size_t) == sizeof(v)) - { - return static_cast(v); - } - else - { - uint8_t* p = reinterpret_cast(&v); + return static_cast(v); + } - return __private_hash__::generic_hash(p, p + sizeof(v)); - } + template + typename etl::enable_if::type + operator ()(T v) const + { + uint8_t* p = reinterpret_cast(&v); + return __private_hash__::generic_hash(p, p + sizeof(v)); } }; @@ -284,18 +287,19 @@ namespace etl template<> struct hash { - size_t operator ()(float v) const + template + typename etl::enable_if::type + operator ()(T v) const { - if (sizeof(size_t) == sizeof(v)) - { - return *reinterpret_cast(&v); - } - else - { - uint8_t* p = reinterpret_cast(&v); + return *reinterpret_cast(&v); + } - return __private_hash__::generic_hash(p, p + sizeof(v)); - } + template + typename etl::enable_if::type + operator ()(T v) const + { + uint8_t* p = reinterpret_cast(&v); + return __private_hash__::generic_hash(p, p + sizeof(v)); } }; @@ -306,18 +310,19 @@ namespace etl template<> struct hash { - size_t operator ()(double v) const + template + typename etl::enable_if::type + operator ()(T v) const { - if (sizeof(size_t) == sizeof(v)) - { - return *reinterpret_cast(&v); - } - else - { - uint8_t* p = reinterpret_cast(&v); + return *reinterpret_cast(&v); + } - return __private_hash__::generic_hash(p, p + sizeof(v)); - } + template + typename etl::enable_if::type + operator ()(T v) const + { + uint8_t* p = reinterpret_cast(&v); + return __private_hash__::generic_hash(p, p + sizeof(v)); } }; @@ -328,18 +333,19 @@ namespace etl template<> struct hash { - size_t operator ()(long double v) const + template + typename etl::enable_if::type + operator ()(T v) const { - if (sizeof(size_t) == sizeof(v)) - { - return *reinterpret_cast(&v); - } - else - { - uint8_t* p = reinterpret_cast(&v); + return *reinterpret_cast(&v); + } - return __private_hash__::generic_hash(p, p + sizeof(v)); - } + template + typename etl::enable_if::type + operator ()(T v) const + { + uint8_t* p = reinterpret_cast(&v); + return __private_hash__::generic_hash(p, p + sizeof(v)); } }; @@ -350,18 +356,34 @@ namespace etl template struct hash { - size_t operator ()(T* v) const + template + typename etl::enable_if::type + operator ()(U* v) const { - if (sizeof(size_t) == sizeof(v)) - { - return reinterpret_cast(v); - } - else - { - uint8_t* p = reinterpret_cast(&v); + return reinterpret_cast(v); + } - return __private_hash__::generic_hash(p, p + sizeof(v)); - } + template + typename etl::enable_if::type + operator ()(const U* v) const + { + return reinterpret_cast(v); + } + + template + typename etl::enable_if::type + operator ()(U* v) const + { + uint8_t* p = reinterpret_cast(&v); + return __private_hash__::generic_hash(p, p + sizeof(v)); + } + + template + typename etl::enable_if::type + operator ()(const U* v) const + { + const uint8_t* p = reinterpret_cast(&v); + return __private_hash__::generic_hash(p, p + sizeof(v)); } }; } From 7957ff0962e5c9005a5889b3c95e76b5dd8ff7b6 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 18:46:40 +0100 Subject: [PATCH 04/34] Removed iterator exception --- src/private/vector_base.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/private/vector_base.h b/src/private/vector_base.h index 026902b6..892245bd 100644 --- a/src/private/vector_base.h +++ b/src/private/vector_base.h @@ -100,20 +100,6 @@ namespace etl } }; - //*************************************************************************** - ///\ingroup vector - /// Vector iterator exception. - //*************************************************************************** - class vector_iterator : public vector_exception - { - public: - - vector_iterator(string_type file_name, numeric_type line_number) - : vector_exception(ETL_ERROR_TEXT("vector:iterator", ETL_FILE"D"), file_name, line_number) - { - } - }; - //*************************************************************************** ///\ingroup vector /// The base class for all templated vector types. From 00115ac9d86995d95a6f1e3c1ecbdaa1403e0c95 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 18:47:51 +0100 Subject: [PATCH 05/34] Removed some ETL errors from the functions. --- src/variant.h | 122 +++++++++++--------------------------------------- 1 file changed, 27 insertions(+), 95 deletions(-) diff --git a/src/variant.h b/src/variant.h index 4c63c6f6..a9b620bf 100644 --- a/src/variant.h +++ b/src/variant.h @@ -48,6 +48,9 @@ SOFTWARE. #pragma diag_suppress 111 #endif +#undef ETL_FILE +#define ETL_FILE "24" + //***************************************************************************** ///\defgroup variant variant /// A class that can contain one a several specified types in a type safe manner. @@ -89,20 +92,7 @@ namespace etl { public: variant_incorrect_type_exception(string_type file_name, numeric_type line_number) - : variant_exception("variant: unsupported type", file_name, line_number) - { - } - }; - - //*************************************************************************** - /// 'type Id' exception for the variant class. - ///\ingroup variant - //*************************************************************************** - class variant_invalid_type_id_exception : public variant_exception - { - public: - variant_invalid_type_id_exception(string_type file_name, numeric_type line_number) - : variant_exception("variant: invalid type id", file_name, line_number) + : variant_exception(ETL_ERROR_TEXT("variant: unsupported type", ETL_FILE"A"), file_name, line_number) { } }; @@ -445,10 +435,7 @@ namespace etl case 5: return reinterpret_cast(*p_data); case 6: return reinterpret_cast(*p_data); case 7: return reinterpret_cast(*p_data); - default: - ETL_ASSERT(false, ETL_ERROR(variant_invalid_type_id_exception)); - return reinterpret_cast(*p_data); - break; + default: return reinterpret_cast(*reinterpret_cast(0)); } } @@ -464,10 +451,7 @@ namespace etl case 5: return reinterpret_cast(*p_data); case 6: return reinterpret_cast(*p_data); case 7: return reinterpret_cast(*p_data); - default: - ETL_ASSERT(false, ETL_ERROR(variant_invalid_type_id_exception)); - return reinterpret_cast(*p_data); - break; + default: return reinterpret_cast(*reinterpret_cast(0)); } } }; @@ -491,10 +475,7 @@ namespace etl case 4: return reinterpret_cast(*p_data); case 5: return reinterpret_cast(*p_data); case 6: return reinterpret_cast(*p_data); - default: - ETL_ASSERT(false, ETL_ERROR(variant_invalid_type_id_exception)); - return reinterpret_cast(*p_data); - break; + default: return reinterpret_cast(*reinterpret_cast(0)); } } @@ -509,10 +490,7 @@ namespace etl case 4: return reinterpret_cast(*p_data); case 5: return reinterpret_cast(*p_data); case 6: return reinterpret_cast(*p_data); - default: - ETL_ASSERT(false, ETL_ERROR(variant_invalid_type_id_exception)); - return reinterpret_cast(*p_data); - break; + default: return reinterpret_cast(*reinterpret_cast(0)); } } }; @@ -535,10 +513,7 @@ namespace etl case 3: return reinterpret_cast(*p_data); case 4: return reinterpret_cast(*p_data); case 5: return reinterpret_cast(*p_data); - default: - ETL_ASSERT(false, ETL_ERROR(variant_invalid_type_id_exception)); - return reinterpret_cast(*p_data); - break; + default: return reinterpret_cast(*reinterpret_cast(0)); } } @@ -552,10 +527,7 @@ namespace etl case 3: return reinterpret_cast(*p_data); case 4: return reinterpret_cast(*p_data); case 5: return reinterpret_cast(*p_data); - default: - ETL_ASSERT(false, ETL_ERROR(variant_invalid_type_id_exception)); - return reinterpret_cast(*p_data); - break; + default: return reinterpret_cast(*reinterpret_cast(0)); } } }; @@ -577,10 +549,7 @@ namespace etl case 2: return reinterpret_cast(*p_data); case 3: return reinterpret_cast(*p_data); case 4: return reinterpret_cast(*p_data); - default: - ETL_ASSERT(false, ETL_ERROR(variant_invalid_type_id_exception)); - return reinterpret_cast(*p_data); - break; + default: return reinterpret_cast(*reinterpret_cast(0)); } } @@ -593,10 +562,7 @@ namespace etl case 2: return reinterpret_cast(*p_data); case 3: return reinterpret_cast(*p_data); case 4: return reinterpret_cast(*p_data); - default: - ETL_ASSERT(false, ETL_ERROR(variant_invalid_type_id_exception)); - return reinterpret_cast(*p_data); - break; + default: return reinterpret_cast(*reinterpret_cast(0)); } } }; @@ -617,10 +583,7 @@ namespace etl case 1: return reinterpret_cast(*p_data); case 2: return reinterpret_cast(*p_data); case 3: return reinterpret_cast(*p_data); - default: - ETL_ASSERT(false, ETL_ERROR(variant_invalid_type_id_exception)); - return reinterpret_cast(*p_data); - break; + default: return reinterpret_cast(*reinterpret_cast(0)); } } @@ -632,10 +595,7 @@ namespace etl case 1: return reinterpret_cast(*p_data); case 2: return reinterpret_cast(*p_data); case 3: return reinterpret_cast(*p_data); - default: - ETL_ASSERT(false, ETL_ERROR(variant_invalid_type_id_exception)); - return reinterpret_cast(*p_data); - break; + default: return reinterpret_cast(*reinterpret_cast(0)); } } }; @@ -655,10 +615,7 @@ namespace etl case 0: return reinterpret_cast(*p_data); case 1: return reinterpret_cast(*p_data); case 2: return reinterpret_cast(*p_data); - default: - ETL_ASSERT(false, ETL_ERROR(variant_invalid_type_id_exception)); - return reinterpret_cast(*p_data); - break; + default: return reinterpret_cast(*reinterpret_cast(0)); } } @@ -669,10 +626,7 @@ namespace etl case 0: return reinterpret_cast(*p_data); case 1: return reinterpret_cast(*p_data); case 2: return reinterpret_cast(*p_data); - default: - ETL_ASSERT(false, ETL_ERROR(variant_invalid_type_id_exception)); - return reinterpret_cast(*p_data); - break; + default: return reinterpret_cast(*reinterpret_cast(0)); } } }; @@ -691,10 +645,7 @@ namespace etl { case 0: return reinterpret_cast(*p_data); case 1: return reinterpret_cast(*p_data); - default: - ETL_ASSERT(false, ETL_ERROR(variant_invalid_type_id_exception)); - return reinterpret_cast(*p_data); - break; + default: return reinterpret_cast(*reinterpret_cast(0)); } } @@ -704,10 +655,7 @@ namespace etl { case 0: return reinterpret_cast(*p_data); case 1: return reinterpret_cast(*p_data); - default: - ETL_ASSERT(false, ETL_ERROR(variant_invalid_type_id_exception)); - return reinterpret_cast(*p_data); - break; + default: return reinterpret_cast(*reinterpret_cast(0)); } } }; @@ -722,26 +670,12 @@ namespace etl TBase& operator()(uint8_t* p_data, uint8_t typeId) { - switch (typeId) - { - case 0: return reinterpret_cast(*p_data); - default: - ETL_ASSERT(false, ETL_ERROR(variant_invalid_type_id_exception)); - return reinterpret_cast(*p_data); - break; - } + return reinterpret_cast(*p_data); } const TBase& operator()(uint8_t* p_data, uint8_t typeId) const { - switch (typeId) - { - case 0: return reinterpret_cast(*p_data); - default: - ETL_ASSERT(false, ETL_ERROR(variant_invalid_type_id_exception)); - return reinterpret_cast(*p_data); - break; - } + return reinterpret_cast(*p_data); } }; @@ -764,7 +698,7 @@ namespace etl /// Forces a STATIC_ASSERT. //*************************************************************************** template - variant(T value) + variant(const T& value) { STATIC_ASSERT(Type_Is_Supported::value, "Unsupported type"); @@ -787,11 +721,11 @@ namespace etl ///\param value The value to assign. //*************************************************************************** template - variant& operator =(typename parameter_type::type value) + variant& operator =(const T& value) { STATIC_ASSERT(Type_Is_Supported::value, "Unsupported type"); - new(data) T(value); + new(static_cast(data)) T(value); type_id = Type_Id_Lookup::type_id; return *this; } @@ -826,9 +760,7 @@ namespace etl case 5: is_same_type = type_id == Type_Id_Lookup::type_id; break; case 6: is_same_type = type_id == Type_Id_Lookup::type_id; break; case 7: is_same_type = type_id == Type_Id_Lookup::type_id; break; - default: - ETL_ASSERT(false, ETL_ERROR(variant_invalid_type_id_exception)); - break; + default: break; } return is_same_type; @@ -850,9 +782,7 @@ namespace etl case 5: reader.read(static_cast(data)); break; case 6: reader.read(static_cast(data)); break; case 7: reader.read(static_cast(data)); break; - default: - ETL_ASSERT(false, ETL_ERROR(variant_invalid_type_id_exception)); - break; + default: break; } } @@ -968,4 +898,6 @@ namespace etl }; } +#undef ETL_FILE + #endif From 8cc41990c47c6cbe02f1d44076d8f8d85c42e24a Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 18:48:12 +0100 Subject: [PATCH 06/34] Refactored the #defines --- src/platform.h | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/src/platform.h b/src/platform.h index 9d4d7e1f..3ada34f8 100644 --- a/src/platform.h +++ b/src/platform.h @@ -28,42 +28,35 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ +// Define the platform. #if defined(__linux__) #define ETL_PLATFORM_LINUX -#endif - -#if defined(__WIN32) || defined(__WIN64) +#elif defined(WIN32) || defined(WIN64) #define ETL_PLATFORM_WINDOWS +#else +#define ETL_PLATFORM_GENERIC #endif +// Define the compiler. #if defined(__IAR_SYSTEMS_ICC__) #define ETL_COMPILER_IAR -#endif - -#if defined(__KEIL__) && !defined(__GNUC__) +#elif defined(__KEIL__) && !defined(__GNUC__) #define ETL_COMPILER_KEIL -#endif - -#if defined(__ghs__) +#elif defined(__ghs__) #define ETL_COMPILER_GREEN_HILLS -#endif - -#if defined(__INTEL_COMPILER) +#elif defined(__INTEL_COMPILER) #define ETL_COMPILER_INTEL -#endif - -#if defined(_MSC_VER) +#elif defined(_MSC_VER) #define ETL_COMPILER_MICROSOFT -#endif - -#if defined(__GNUC__) +#elif defined(__GNUC__) #define ETL_COMPILER_GCC +#else +#define ETL_COMPILER_GENERIC #endif #if (defined(ETL_COMPILER_MICROSOFT) && (_MSC_VER < 1600)) || \ defined(ETL_COMPILER_KEIL) || \ defined(ETL_COMPILER_IAR) || \ (defined(ETL_COMPILER_GCC) && (__cplusplus < 201103L)) - #define NO_NULLPTR_SUPPORT -#endif - +#define NO_NULLPTR_SUPPORT +#endif \ No newline at end of file From ec74c52fbcffceeb7ccf20bc2b21bf6a50af4b8b Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 18:49:21 +0100 Subject: [PATCH 07/34] Removed ETL_ASSERT and commented out debug code. --- src/ivector.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/ivector.h b/src/ivector.h index 5ce7374c..39659469 100644 --- a/src/ivector.h +++ b/src/ivector.h @@ -271,13 +271,6 @@ namespace etl reference at(size_t i) { ETL_ASSERT(i < current_size, ETL_ERROR(vector_out_of_bounds)); - -// if (i >= current_size) -// { -// -// throw etl::vector_out_of_bounds("a", 1); -// } - return p_buffer[i]; } @@ -359,7 +352,6 @@ namespace etl { #ifdef _DEBUG difference_type count = std::distance(first, last); - ETL_ASSERT(count >= 0, ETL_ERROR(vector_iterator)); ETL_ASSERT(static_cast(count) <= MAX_SIZE, ETL_ERROR(vector_full)); #endif From 55179454f278788c00b91e4cdaed4cb7c4696275 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 18:50:00 +0100 Subject: [PATCH 08/34] Removed condition from splice() --- src/ilist.h | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/ilist.h b/src/ilist.h index 8dc3dbc9..b969f71d 100644 --- a/src/ilist.h +++ b/src/ilist.h @@ -781,11 +781,8 @@ namespace etl { if (&other == this) { - if (from != to) - { - // Internal move. - move(to, from); - } + // Internal move. + move(to, from); } else { @@ -802,11 +799,8 @@ namespace etl { if (&other == this) { - if (first != to) - { - // Internal move. - move(to, first, last); - } + // Internal move. + move(to, first, last); } else { From 74c8bf0e204cfc84f24da2bafdb689b7bc13b8ef Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 18:51:00 +0100 Subject: [PATCH 09/34] Fixed bugs in pop_front and insert_after. --- src/iforward_list.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/iforward_list.h b/src/iforward_list.h index 775cace0..98ecdc20 100644 --- a/src/iforward_list.h +++ b/src/iforward_list.h @@ -426,7 +426,7 @@ namespace etl void pop_front() { #if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(forward_list_empty)); + ETL_ASSERT(!empty(), ETL_ERROR(forward_list_empty)); #endif remove_node_after(start_node); } @@ -500,7 +500,7 @@ namespace etl { // Set up the next free node. Data_Node& data_node = allocate_data_node(value); - insert_node(*position.p_node, data_node); + insert_node_after(*position.p_node, data_node); } } From 39b967e6dcb860186bb9e9128241d0050e9cb7c0 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 18:51:43 +0100 Subject: [PATCH 10/34] Changed test in assign range --- src/iflat_set.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/iflat_set.h b/src/iflat_set.h index b39d5ab9..55ca571a 100644 --- a/src/iflat_set.h +++ b/src/iflat_set.h @@ -200,7 +200,7 @@ namespace etl { #ifdef _DEBUG difference_type count = std::distance(first, last); - ETL_ASSERT(count >= 0, ETL_ERROR(flat_set_iterator)); + ETL_ASSERT(count <= difference_type(capacity()), ETL_ERROR(flat_set_full)); #endif clear(); From fac8b9e6e992ea5aafa16a4617cd21c97a9c7276 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 18:52:02 +0100 Subject: [PATCH 11/34] Changed test in assign range --- src/iflat_multimap.h | 6 +++--- src/iflat_multiset.h | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/iflat_multimap.h b/src/iflat_multimap.h index 644f505b..e5fa864e 100644 --- a/src/iflat_multimap.h +++ b/src/iflat_multimap.h @@ -224,7 +224,7 @@ namespace etl { #ifdef _DEBUG difference_type count = std::distance(first, last); - ETL_ASSERT(count >= 0, ETL_ERROR(flat_multimap_iterator)); + ETL_ASSERT(count <= difference_type(capacity()), ETL_ERROR(flat_multimap_full)); #endif clear(); @@ -242,12 +242,12 @@ namespace etl //********************************************************************* std::pair insert(const value_type& value) { + ETL_ASSERT(!buffer.full(), ETL_ERROR(flat_multimap_full)); + std::pair result(end(), false); iterator i_element = lower_bound(value.first); - ETL_ASSERT(!buffer.full(), ETL_ERROR(flat_multimap_full)); - if (i_element == end()) { // At the end. diff --git a/src/iflat_multiset.h b/src/iflat_multiset.h index 0f4f7efa..135511c0 100644 --- a/src/iflat_multiset.h +++ b/src/iflat_multiset.h @@ -200,8 +200,7 @@ namespace etl { #ifdef _DEBUG difference_type count = std::distance(first, last); - - ETL_ASSERT(count >= 0, ETL_ERROR(flat_multiset_iterator)); + ETL_ASSERT(count <= difference_type(capacity()), ETL_ERROR(flat_multiset_full)); #endif clear(); From 1f1952bfab71a054a31e38e07dcb13bad442a3bb Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 18:52:30 +0100 Subject: [PATCH 12/34] Removed ETL_ASSERT in assign --- src/iflat_map.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/iflat_map.h b/src/iflat_map.h index 5a1bc337..399897f2 100644 --- a/src/iflat_map.h +++ b/src/iflat_map.h @@ -273,8 +273,6 @@ namespace etl { #ifdef _DEBUG difference_type count = std::distance(first, last); - - ETL_ASSERT(count >= 0, ETL_ERROR(flat_map_iterator)); ETL_ASSERT(count <= difference_type(capacity()), ETL_ERROR(flat_map_full)); #endif From 7f3f214a1e4f1826eca254b13bd8f0bcb61c9a5d Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 18:52:51 +0100 Subject: [PATCH 13/34] Removed flat_set_out_of_bounds exception class --- src/private/flat_set_base.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/private/flat_set_base.h b/src/private/flat_set_base.h index e61e8a24..22d1c58f 100644 --- a/src/private/flat_set_base.h +++ b/src/private/flat_set_base.h @@ -74,20 +74,6 @@ namespace etl } }; - //*************************************************************************** - ///\ingroup flat_set - /// Vector out of bounds exception. - //*************************************************************************** - class flat_set_out_of_bounds : public flat_set_exception - { - public: - - flat_set_out_of_bounds(string_type file_name, numeric_type line_number) - : flat_set_exception(ETL_ERROR_TEXT("flat_set:bounds", ETL_FILE"B"), file_name, line_number) - { - } - }; - //*************************************************************************** ///\ingroup flat_set /// Vector iterator exception. From aa47131958f6c0b9ff7d560d4138e0e5272dedd0 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 18:53:29 +0100 Subject: [PATCH 14/34] Removed flat_multiset_out_of_bounds & flat_multiset_iterator exception classes. --- src/private/flat_multiset_base.h | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/src/private/flat_multiset_base.h b/src/private/flat_multiset_base.h index 1e1e2007..4b495ddf 100644 --- a/src/private/flat_multiset_base.h +++ b/src/private/flat_multiset_base.h @@ -74,34 +74,6 @@ namespace etl } }; - //*************************************************************************** - ///\ingroup flat_multiset - /// Flat multiset out of bounds exception. - //*************************************************************************** - class flat_multiset_out_of_bounds : public flat_multiset_exception - { - public: - - flat_multiset_out_of_bounds(string_type file_name, numeric_type line_number) - : flat_multiset_exception(ETL_ERROR_TEXT("flat_multiset:bounds", ETL_FILE"B"), file_name, line_number) - { - } - }; - - //*************************************************************************** - ///\ingroup flat_multiset - /// Vector iterator exception. - //*************************************************************************** - class flat_multiset_iterator : public flat_multiset_exception - { - public: - - flat_multiset_iterator(string_type file_name, numeric_type line_number) - : flat_multiset_exception(ETL_ERROR_TEXT("flat_multiset:iterator", ETL_FILE"C"), file_name, line_number) - { - } - }; - //*************************************************************************** ///\ingroup flat_multiset /// The base class for all templated flat_multiset types. From 93c2b4bb815513bdde8d1ec61fb4cad84a6ba3f9 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 18:53:52 +0100 Subject: [PATCH 15/34] Removed flat_multimap_out_of_bounds & flat_multimap_iterator exception classes. --- src/private/flat_multimap_base.h | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/src/private/flat_multimap_base.h b/src/private/flat_multimap_base.h index 74473b21..eb9840f2 100644 --- a/src/private/flat_multimap_base.h +++ b/src/private/flat_multimap_base.h @@ -74,34 +74,6 @@ namespace etl } }; - //*************************************************************************** - ///\ingroup flat_multimap - /// Vector out of bounds exception. - //*************************************************************************** - class flat_multimap_out_of_bounds : public flat_multimap_exception - { - public: - - flat_multimap_out_of_bounds(string_type file_name, numeric_type line_number) - : flat_multimap_exception(ETL_ERROR_TEXT("flat_multimap:bounds", ETL_FILE"B"), file_name, line_number) - { - } - }; - - //*************************************************************************** - ///\ingroup flat_multimap - /// Vector iterator exception. - //*************************************************************************** - class flat_multimap_iterator : public flat_multimap_exception - { - public: - - flat_multimap_iterator(string_type file_name, numeric_type line_number) - : flat_multimap_exception(ETL_ERROR_TEXT("flat_multimap:iterator", ETL_FILE"C"), file_name, line_number) - { - } - }; - //*************************************************************************** ///\ingroup flat_multimap /// The base class for all templated flat_multimap types. From f9a9c3a0bd6c3f774fec67099d1dd176013e2561 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 18:54:14 +0100 Subject: [PATCH 16/34] Removed flat_map_iterator exception class. --- src/private/flat_map_base.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/private/flat_map_base.h b/src/private/flat_map_base.h index ee410425..16fd8587 100644 --- a/src/private/flat_map_base.h +++ b/src/private/flat_map_base.h @@ -88,20 +88,6 @@ namespace etl } }; - //*************************************************************************** - ///\ingroup flat_map - /// Vector iterator exception. - //*************************************************************************** - class flat_map_iterator : public flat_map_exception - { - public: - - flat_map_iterator(string_type file_name, numeric_type line_number) - : flat_map_exception(ETL_ERROR_TEXT("flat_map:iterator", ETL_FILE"C"), file_name, line_number) - { - } - }; - //*************************************************************************** ///\ingroup flat_map /// The base class for all templated flat_map types. From c12aacf1714f9dbd392148be502eefd758912732 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 18:55:37 +0100 Subject: [PATCH 17/34] Added test_resize_down_value Added test_pop_back_exception Added test_const_reverse_iterator2 --- test/test_vector.cpp | 60 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/test/test_vector.cpp b/test/test_vector.cpp index d05f07b5..2bd8a5e8 100644 --- a/test/test_vector.cpp +++ b/test/test_vector.cpp @@ -272,6 +272,19 @@ namespace CHECK_EQUAL(data.size(), NEW_SIZE); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_resize_down_value) + { + const size_t INITIAL_SIZE = 5; + const size_t NEW_SIZE = 2; + const int INITIAL_VALUE = 1; + + Data data(INITIAL_SIZE); + data.resize(NEW_SIZE, INITIAL_VALUE); + + CHECK_EQUAL(data.size(), NEW_SIZE); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_empty) { @@ -531,6 +544,19 @@ namespace CHECK(is_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_pop_back_exception) + { + Data data; + + data.resize(2); + + data.pop_back(); + data.pop_back(); + + CHECK_THROW(data.pop_back(), etl::vector_empty); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_insert_position_value) { @@ -732,8 +758,8 @@ namespace Data data(compare_data.begin(), compare_data.end()); bool is_equal = std::equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(is_equal); } @@ -746,8 +772,8 @@ namespace Data data(compare_data.begin(), compare_data.end()); bool is_equal = std::equal(data.cbegin(), - data.cend(), - compare_data.cbegin()); + data.cend(), + compare_data.cbegin()); CHECK(is_equal); } @@ -760,8 +786,8 @@ namespace Data data(compare_data.begin(), compare_data.end()); bool is_equal = std::equal(data.rbegin(), - data.rend(), - compare_data.rbegin()); + data.rend(), + compare_data.rbegin()); CHECK(is_equal); } @@ -769,13 +795,27 @@ namespace //************************************************************************* TEST_FIXTURE(SetupFixture, test_const_reverse_iterator) { - Compare_Data compare_data(initial_data.begin(), initial_data.end()); + const Compare_Data compare_data(initial_data.begin(), initial_data.end()); - Data data(compare_data.begin(), compare_data.end()); + const Data data(compare_data.begin(), compare_data.end()); bool is_equal = std::equal(data.crbegin(), - data.crend(), - compare_data.crbegin()); + data.crend(), + compare_data.crbegin()); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_const_reverse_iterator2) + { + const Compare_Data compare_data(initial_data.begin(), initial_data.end()); + + const Data data(compare_data.begin(), compare_data.end()); + + bool is_equal = std::equal(data.rbegin(), + data.rend(), + compare_data.rbegin()); CHECK(is_equal); } From b6fd26f58a91ae1e2357a59b7068d474dfaa41b1 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 19:16:07 +0100 Subject: [PATCH 18/34] Added test_jenkins_32_finalised_exception --- test/test_jenkins.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/test_jenkins.cpp b/test/test_jenkins.cpp index ac9b104d..3bef5bf2 100644 --- a/test/test_jenkins.cpp +++ b/test/test_jenkins.cpp @@ -149,6 +149,18 @@ namespace CHECK_EQUAL(compare2, hash3); } + //************************************************************************* + TEST(test_jenkins_32_finalised_exception) + { + std::string data("123456789"); + + etl::jenkins j32; + j32.add(data.begin(), data.end()); + uint32_t hash = j32; + + CHECK_THROW(j32.add(0), etl::hash_finalised); + } + //************************************************************************* TEST(test_jenkins_64_constructor) { From 3a8cfda2c2f802b1d7922ecfdee5c522d920baea Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 19:16:31 +0100 Subject: [PATCH 19/34] Fixed floating point hashes --- test/test_hash.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/test/test_hash.cpp b/test/test_hash.cpp index 1487c806..79a9fe8a 100644 --- a/test/test_hash.cpp +++ b/test/test_hash.cpp @@ -148,10 +148,7 @@ namespace { size_t hash = etl::hash()((float)(1.2345)); - if (sizeof(size_t) == sizeof(long long)) - CHECK_EQUAL(0x884B5E3F478AF88F, hash); - else - CHECK_EQUAL(0x3F9E0419, hash); + CHECK_EQUAL(0X3F9E0419, hash); } //************************************************************************* @@ -159,8 +156,8 @@ namespace { size_t hash = etl::hash()((double)(1.2345)); - if (sizeof(size_t) == sizeof(long long)) - CHECK_EQUAL(0x3FF3C083126E978D, hash); + if (sizeof(size_t) == sizeof(double)) + CHECK_EQUAL(0X3FF3C083126E978D, hash); else CHECK_EQUAL(0x86FBF224, hash); } From 8d59c170efbf766b5cfddca79906eab73f8b34bd Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 19:16:53 +0100 Subject: [PATCH 20/34] Added test_pop_excess --- test/test_stack.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/test_stack.cpp b/test/test_stack.cpp index a0fe32e4..886279e9 100644 --- a/test/test_stack.cpp +++ b/test/test_stack.cpp @@ -179,6 +179,24 @@ namespace CHECK_EQUAL(1U, stack.size()); } + //************************************************************************* + TEST(test_pop_excess) + { + etl::stack stack; + + for (size_t i = 0; i < stack.max_size(); ++i) + { + stack.push(1); + } + + for (size_t i = 0; i < stack.max_size(); ++i) + { + stack.pop(); + } + + CHECK_THROW(stack.pop(), etl::stack_empty); + } + //************************************************************************* TEST(test_top) { From dfbd0391a2b6068a9efb4ccf7ba66bd8fa9f5a6a Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 19:17:26 +0100 Subject: [PATCH 21/34] Added various tests --- test/test_binary.cpp | 94 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 87 insertions(+), 7 deletions(-) diff --git a/test/test_binary.cpp b/test/test_binary.cpp index e2f2549f..6ac27823 100644 --- a/test/test_binary.cpp +++ b/test/test_binary.cpp @@ -97,6 +97,19 @@ TReturn test_fold_bits(uint64_t value, int size) return result; } +// Slow gray to binary +template +T compare_gray_to_binary(T value) +{ + T mask; + for (mask = value >> 1; mask != 0; mask = mask >> 1) + { + value = value ^ mask; + } + + return value; +} + namespace { SUITE(test_binary) @@ -393,13 +406,16 @@ namespace TEST(test_rotate16) { uint16_t value; + int offset; + offset = 4; value = 0xB73C; - value = etl::rotate(value, 4); + value = etl::rotate(value, offset); CHECK_EQUAL(0x73CB, int(value)); + offset = -4; value = 0xB73C; - value = etl::rotate(value, -4); + value = etl::rotate(value, offset); CHECK_EQUAL(0xCB73, int(value)); } @@ -523,6 +539,24 @@ namespace CHECK_EQUAL(0xA5A55A5AU, value); } + //************************************************************************* + TEST(test_reverse_bytes64) + { + uint64_t value; + + value = 0x0123456789ABCDEF; + value = etl::reverse_bytes(value); + CHECK_EQUAL(0xEFCDAB8967452301U, value); + + value = 0xA5A55A5AA5A55A5A; + value = etl::reverse_bytes(value); + CHECK_EQUAL(0x5A5AA5A55A5AA5A5U, value); + + value = 0x5A5AA5A55A5AA5A5; + value = etl::reverse_bytes(value); + CHECK_EQUAL(0xA5A55A5AA5A55A5AU, value); + } + //************************************************************************* TEST(test_binary_to_gray8) { @@ -608,11 +642,57 @@ namespace } //************************************************************************* - TEST(test_count_bits_8) + TEST(test_gray_to_binary8) + { + for (size_t i = 1; i <= std::numeric_limits::max(); ++i) + { + CHECK_EQUAL(compare_gray_to_binary(uint8_t(i)), etl::gray_to_binary(uint8_t(i))); + } + } + + //************************************************************************* + TEST(test_gray_to_binary16) { for (size_t i = 1; i <= std::numeric_limits::max(); ++i) { - CHECK_EQUAL(test_count(i), etl::count_bits(i)); + CHECK_EQUAL(compare_gray_to_binary(uint16_t(i)), etl::gray_to_binary(uint16_t(i))); + } + } + + //************************************************************************* + TEST(test_gray_to_binary32) + { + etl::fnv_1a_32 hash; + + hash.add(1); + + for (size_t i = 1; i < 1000000; ++i) + { + uint32_t value = hash.value(); + CHECK_EQUAL(compare_gray_to_binary(value), etl::gray_to_binary(value)); + } + } + + //************************************************************************* + TEST(test_gray_to_binary64) + { + etl::fnv_1a_64 hash; + + hash.add(1); + + for (size_t i = 1; i < 1000000; ++i) + { + uint64_t value = hash.value(); + CHECK_EQUAL(compare_gray_to_binary(value), etl::gray_to_binary(value)); + } + } + + //************************************************************************* + TEST(test_count_bits_8) + { + for (size_t i = 1; i <= std::numeric_limits::max(); ++i) + { + CHECK_EQUAL(test_count(i), etl::count_bits(uint8_t(i))); } } @@ -621,7 +701,7 @@ namespace { for (size_t i = 1; i <= std::numeric_limits::max(); ++i) { - CHECK_EQUAL(test_count(i), etl::count_bits(i)); + CHECK_EQUAL(test_count(i), etl::count_bits(uint16_t(i))); } } @@ -660,7 +740,7 @@ namespace { for (size_t i = 1; i <= std::numeric_limits::max(); ++i) { - CHECK_EQUAL(test_parity(i), etl::parity(i)); + CHECK_EQUAL(test_parity(i), etl::parity(uint8_t(i))); } } @@ -669,7 +749,7 @@ namespace { for (size_t i = 1; i <= std::numeric_limits::max(); ++i) { - CHECK_EQUAL(test_parity(i), etl::parity(i)); + CHECK_EQUAL(test_parity(i), etl::parity(uint16_t(i))); } } From 01a94919e369f9c0921d8f5971a4fff944a2bcab Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 19:18:13 +0100 Subject: [PATCH 22/34] Added test_pop_back_exception & test_pop_front_exception --- test/test_deque.cpp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/test/test_deque.cpp b/test/test_deque.cpp index 5d140040..e97efee9 100644 --- a/test/test_deque.cpp +++ b/test/test_deque.cpp @@ -1215,6 +1215,23 @@ namespace CHECK_EQUAL(size_t(0), data.size()); } + //************************************************************************* + TEST(test_pop_back_exception) + { + Compare_Data compare_data = { N1, N2, N3, N4, N5 }; + DataNDC data; + + data.assign(compare_data.begin(), compare_data.end()); + + data.pop_back(); + data.pop_back(); + data.pop_back(); + data.pop_back(); + data.pop_back(); + + CHECK_THROW(data.pop_back(), etl::deque_empty); + } + //************************************************************************* TEST(test_push_front_null) { @@ -1284,6 +1301,23 @@ namespace CHECK_THROW(data.push_front(N999), etl::deque_full); } + //************************************************************************* + TEST(test_pop_front_exception) + { + Compare_Data compare_data = { N1, N2, N3, N4, N5 }; + DataNDC data; + + data.assign(compare_data.begin(), compare_data.end()); + + data.pop_front(); + data.pop_front(); + data.pop_front(); + data.pop_front(); + data.pop_front(); + + CHECK_THROW(data.pop_front(), etl::deque_empty); + } + //************************************************************************* TEST(test_push_front_push_back) { From fe1e05a8100afd4f9f9acb7093a4b0a529c7f675 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 19:18:41 +0100 Subject: [PATCH 23/34] Added test_at_out_of_bounds & test_const_at_out_of_bounds --- test/test_flat_map.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/test_flat_map.cpp b/test/test_flat_map.cpp index 3f36618a..2c8ab72c 100644 --- a/test/test_flat_map.cpp +++ b/test/test_flat_map.cpp @@ -321,6 +321,14 @@ namespace CHECK_EQUAL(data.at(9), compare_data.at(9)); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_at_out_of_bounds) + { + DataNDC data(initial_data.begin(), initial_data.end()); + + CHECK_THROW(data.at(10), etl::flat_map_out_of_bounds); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_at_const) { @@ -339,6 +347,15 @@ namespace CHECK_EQUAL(data.at(9), compare_data.at(9)); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_at_const_out_of_bounds) + { + const DataNDC data(initial_data.begin(), initial_data.end()); + + CHECK_THROW(data.at(10), etl::flat_map_out_of_bounds); + } + + //************************************************************************* TEST_FIXTURE(SetupFixture, test_assign_range) { From 0d43347c0cceda56f1261cf9f61e273a8cc91763 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 19:19:05 +0100 Subject: [PATCH 24/34] Added many new tests --- test/test_forward_list.cpp | 191 +++++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) diff --git a/test/test_forward_list.cpp b/test/test_forward_list.cpp index 3906a525..45d35805 100644 --- a/test/test_forward_list.cpp +++ b/test/test_forward_list.cpp @@ -155,6 +155,24 @@ namespace CHECK(are_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_resize_up) + { + const size_t INITIAL_SIZE = 4; + const size_t NEW_SIZE = 8; + const ItemNDC VALUE("1"); + + DataNDC data(INITIAL_SIZE, VALUE); + data.resize(NEW_SIZE); + + CompareDataNDC compare_data(INITIAL_SIZE, VALUE); + compare_data.resize(NEW_SIZE); + + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + + CHECK(are_equal); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_resize_up_value) { @@ -189,6 +207,24 @@ namespace const size_t NEW_SIZE = 2; const ItemNDC VALUE("1"); + DataNDC data(INITIAL_SIZE, VALUE); + data.resize(NEW_SIZE); + + CompareDataNDC compare_data(INITIAL_SIZE, VALUE); + compare_data.resize(NEW_SIZE); + + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + + CHECK(are_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_resize_down_value) + { + const size_t INITIAL_SIZE = 4; + const size_t NEW_SIZE = 2; + const ItemNDC VALUE("1"); + DataNDC data(INITIAL_SIZE, VALUE); data.resize(NEW_SIZE, VALUE); @@ -293,6 +329,47 @@ namespace CHECK(are_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_after_position_size_value) + { + const size_t INITIAL_SIZE = 4; + const ItemNDC VALUE("1"); + const ItemNDC INSERT_VALUE("2"); + + CompareDataNDC compare_data(INITIAL_SIZE, VALUE); + DataNDC data(INITIAL_SIZE, VALUE); + + size_t offset = 2; + + DataNDC::iterator i_data = data.begin(); + std::advance(i_data, offset); + + CompareDataNDC::iterator i_compare_data = compare_data.begin(); + std::advance(i_compare_data, offset); + + data.insert_after(i_data, 2, INSERT_VALUE); + compare_data.insert_after(i_compare_data, 2, INSERT_VALUE); + + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + + CHECK(are_equal); + + offset = 0; + + i_data = data.begin(); + std::advance(i_data, offset); + + i_compare_data = compare_data.begin(); + std::advance(i_compare_data, offset); + + data.insert_after(i_data, 2, INSERT_VALUE); + compare_data.insert_after(i_compare_data, 2, INSERT_VALUE); + + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + + CHECK(are_equal); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_insert_after_range) { @@ -354,6 +431,61 @@ namespace CHECK(are_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_push_front_null) + { + CompareDataNDC compare_data; + DataNDC data; + + compare_data.push_front(ItemNDC("1")); + compare_data.push_front(ItemNDC("2")); + compare_data.push_front(ItemNDC("3")); + compare_data.push_front(ItemNDC("4")); + compare_data.push_front(ItemNDC("5")); + compare_data.push_front(ItemNDC("6")); + + CHECK_NO_THROW(data.push_front()); + data.front() = ItemNDC("1"); + CHECK_NO_THROW(data.push_front()); + data.front() = ItemNDC("2"); + CHECK_NO_THROW(data.push_front()); + data.front() = ItemNDC("3"); + CHECK_NO_THROW(data.push_front()); + data.front() = ItemNDC("4"); + CHECK_NO_THROW(data.push_front()); + data.front() = ItemNDC("5"); + CHECK_NO_THROW(data.push_front()); + data.front() = ItemNDC("6"); + + CHECK_EQUAL(6, data.size()); + CHECK_EQUAL(6, std::distance(data.begin(), data.end())); + + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + + CHECK(are_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_front_const) + { + const DataNDC data(sorted_data.begin(), sorted_data.end()); + + CHECK_EQUAL(ItemNDC("0"), data.front()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_before_begin_const) + { + const DataNDC data(sorted_data.begin(), sorted_data.end()); + + DataNDC::const_iterator itr = data.before_begin(); + ++itr; + + are_equal = std::equal(data.begin(), data.end(), itr); + + CHECK(are_equal); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_push_front_excess) { @@ -387,6 +519,24 @@ namespace CHECK(data.empty()); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_pop_front_empty) + { + DataNDC data; + + CHECK_NO_THROW(data.push_front(ItemNDC("0"))); + CHECK_NO_THROW(data.push_front(ItemNDC("1"))); + CHECK_NO_THROW(data.push_front(ItemNDC("2"))); + CHECK_NO_THROW(data.push_front(ItemNDC("3"))); + + data.pop_front(); + data.pop_front(); + data.pop_front(); + data.pop_front(); + + CHECK_THROW(data.pop_front(), etl::forward_list_empty); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_erase_after_single) { @@ -620,6 +770,20 @@ namespace CHECK(are_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_reverse_empty) + { + CompareDataNDC compare_data; + DataNDC data; + + compare_data.reverse(); + data.reverse(); + + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + + CHECK(are_equal); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_sort) { @@ -634,6 +798,20 @@ namespace CHECK(are_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_sort_empty) + { + CompareDataNDC compare_data; + DataNDC data; + + compare_data.sort(); + data.sort(); + + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + + CHECK(are_equal); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_move) { @@ -843,5 +1021,18 @@ namespace CHECK_THROW(data.move_after(i_first_before, i_last, i_to_before), etl::forward_list_iterator); } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_binary_comparisons) + { + DataNDC data1(sorted_data.begin(), sorted_data.end()); + DataNDC data2(sorted_data.begin(), sorted_data.end()); + DataNDC data3(unsorted_data.begin(), unsorted_data.end()); + + CHECK(data1 == data2); + CHECK(data1 != data3); + CHECK(data1 < data3); + CHECK(data3 > data1); + } }; } From fc272fce209092981e5316e73da69ee235385644 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 19:19:34 +0100 Subject: [PATCH 25/34] Added test_pop_exception --- test/test_queue.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/test_queue.cpp b/test/test_queue.cpp index 60637cdf..e2634cca 100644 --- a/test/test_queue.cpp +++ b/test/test_queue.cpp @@ -300,6 +300,19 @@ namespace CHECK_EQUAL(1U, queue.size()); } + //************************************************************************* + TEST(test_pop_exception) + { + etl::queue queue; + + queue.push(1); + queue.push(2); + queue.pop(); + queue.pop(); + + CHECK_THROW(queue.pop(), etl::queue_empty); + } + //************************************************************************* TEST(test_assignment) { From 7611cfb905f5fb6da4f7461916ea826594f3fe36 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 19:19:56 +0100 Subject: [PATCH 26/34] Added many more variant tests --- test/test_variant.cpp | 287 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 236 insertions(+), 51 deletions(-) diff --git a/test/test_variant.cpp b/test/test_variant.cpp index e2d64686..9b4be85e 100644 --- a/test/test_variant.cpp +++ b/test/test_variant.cpp @@ -75,8 +75,18 @@ struct derived_2 : public base }; // Test variant types. -typedef etl::variant test_variant_1; -typedef etl::variant test_variant_2; +typedef etl::variant test_variant_3a; +typedef etl::variant test_variant_3b; + +typedef etl::variant test_variant_1; +typedef etl::variant test_variant_2; +typedef etl::variant test_variant_3; +typedef etl::variant test_variant_4; +typedef etl::variant test_variant_5; +typedef etl::variant test_variant_6; +typedef etl::variant test_variant_7; +typedef etl::variant test_variant_8; + typedef etl::variant test_variant_polymorphic; typedef etl::variant test_variant_max_types; @@ -108,7 +118,7 @@ namespace //************************************************************************* TEST(test_constructor_default) { - CHECK_NO_THROW(test_variant_1 variant); + CHECK_NO_THROW(test_variant_3a variant); } //************************************************************************* @@ -116,7 +126,7 @@ namespace { // Char. char c = 'a'; - test_variant_1 variant_char(c); + test_variant_3a variant_char(c); CHECK(variant_char.is_type()); CHECK(variant_char.is_valid()); @@ -124,7 +134,7 @@ namespace // Int. int i = 1; - test_variant_1 variant_int(i); + test_variant_3a variant_int(i); CHECK(variant_int.is_type()); CHECK(variant_int.is_valid()); @@ -132,7 +142,7 @@ namespace // String. std::string text("Some Text"); - test_variant_1 variant_text(text); + test_variant_3a variant_text(text); CHECK(variant_text.is_type()); CHECK(variant_text.is_valid()); @@ -143,9 +153,9 @@ namespace TEST(test_copy_constructor) { std::string text("Some Text"); - test_variant_1 variant_1(text); + test_variant_3a variant_1(text); - test_variant_1 variant_2(variant_1); + test_variant_3a variant_2(variant_1); CHECK(variant_1.is_same_type(variant_2)); CHECK(variant_2.is_valid()); @@ -156,7 +166,7 @@ namespace TEST(test_assign_from_value) { std::string text("Some Text"); - test_variant_1 variant; + test_variant_3a variant; variant = text; @@ -168,8 +178,8 @@ namespace TEST(test_assign_from_variant) { std::string text("Some Text"); - test_variant_1 variant_1; - test_variant_1 variant_2; + test_variant_3a variant_1; + test_variant_3a variant_2; variant_1 = text; variant_2 = variant_1; @@ -182,7 +192,7 @@ namespace TEST(test_assignment_incorrect_type_exception) { std::string text("Some Text"); - test_variant_1 variant; + test_variant_3a variant; variant = text; int i; @@ -194,8 +204,8 @@ namespace TEST(test_is_same_type) { std::string text("Some Text"); - test_variant_1 variant_1; - test_variant_1 variant_2; + test_variant_3a variant_1; + test_variant_3a variant_2; variant_1 = 1; variant_2 = 2; @@ -211,8 +221,8 @@ namespace //************************************************************************* TEST(test_is_same_type_different_variants) { - test_variant_1 variant_1; - test_variant_2 variant_2; + test_variant_3a variant_1; + test_variant_3b variant_2; variant_1 = 1; variant_2 = 2; @@ -226,18 +236,18 @@ namespace } //************************************************************************* - TEST(Testis_supported_type) + TEST(test_is_supported_type) { - CHECK(test_variant_1::is_supported_type()); - CHECK(test_variant_1::is_supported_type()); - CHECK(test_variant_1::is_supported_type()); - CHECK(!test_variant_1::is_supported_type()); + CHECK(test_variant_3a::is_supported_type()); + CHECK(test_variant_3a::is_supported_type()); + CHECK(test_variant_3a::is_supported_type()); + CHECK(!test_variant_3a::is_supported_type()); } //************************************************************************* - TEST(TestIsValid) + TEST(test_is_valid) { - test_variant_1 variant; + test_variant_3a variant; CHECK(!variant.is_valid()); @@ -246,9 +256,9 @@ namespace } //************************************************************************* - TEST(TestIsType) + TEST(test_is_type) { - test_variant_1 variant; + test_variant_3a variant; variant = 1; CHECK(variant.is_type()); @@ -260,9 +270,9 @@ namespace } //************************************************************************* - TEST(TestGet) + TEST(test_get) { - test_variant_1 variant; + test_variant_3a variant; variant = 1; CHECK_EQUAL(1, variant.get()); @@ -274,11 +284,29 @@ namespace CHECK_EQUAL(std::string("Some Text"), variant.get()); } + //************************************************************************* + TEST(test_get_const) + { + test_variant_3a variant; + + variant = 1; + const test_variant_3a cvariant1(variant); + CHECK_EQUAL(1, cvariant1.get()); + + variant = 'a'; + const test_variant_3a cvariant2(variant); + CHECK_EQUAL('a', cvariant2.get()); + + variant = std::string("Some Text"); + const test_variant_3a cvariant3(variant); + CHECK_EQUAL(std::string("Some Text"), cvariant3.get()); + } + //************************************************************************* TEST(test_assignment) { - test_variant_1 variant1; - test_variant_1 variant2; + test_variant_3a variant1; + test_variant_3a variant2; variant1 = 1; variant2 = variant1; @@ -289,7 +317,7 @@ namespace //************************************************************************* TEST(test_self_assignment) { - test_variant_1 variant; + test_variant_3a variant; variant = 1; variant = variant; @@ -300,18 +328,18 @@ namespace //************************************************************************* TEST(TestGetException) { - test_variant_1 variant; + test_variant_3a variant; variant = 1; char c; - CHECK_THROW(c = variant.get(), etl::variant_exception); + CHECK_THROW(c = variant.get(), etl::variant_incorrect_type_exception); (void)c; } //************************************************************************* TEST(TestGetReference) { - test_variant_1 variant; + test_variant_3a variant; variant = 1; int& ir = variant.get(); @@ -324,7 +352,7 @@ namespace //************************************************************************* TEST(TestGetConstReference) { - test_variant_1 variant; + test_variant_3a variant; variant = 1; const int& ir = variant.get(); CHECK_EQUAL(1, ir); @@ -336,7 +364,7 @@ namespace //************************************************************************* TEST(TestCallReader) { - class reader : public test_variant_1::reader + class reader : public test_variant_3a::reader { public: @@ -364,7 +392,7 @@ namespace int i; }; - test_variant_1 variant; + test_variant_3a variant; reader reader; variant = 'a'; @@ -381,26 +409,183 @@ namespace } //************************************************************************* - TEST(TestConversionOperators) + TEST(test_conversion_operators) { - test_variant_1 variant; - variant = 1; - int i = variant; - CHECK_EQUAL(i, variant.get()); + int8_t i8; + uint8_t ui8; + int16_t i16; + uint16_t ui16; + int32_t i32; + uint32_t ui32; + int64_t i64; + uint64_t ui64; - variant = std::string("Some Text"); - std::string text = variant; - CHECK_EQUAL(text, variant.get()); + test_variant_1 variant1; + test_variant_2 variant2; + test_variant_3 variant3; + test_variant_4 variant4; + test_variant_5 variant5; + test_variant_6 variant6; + test_variant_7 variant7; + test_variant_8 variant8; - variant = 'a'; - char c = variant; - CHECK_EQUAL(c, variant.get()); + // Variant 1 + variant1 = int8_t(1); + i8 = variant1; + CHECK_EQUAL(i8, variant1.get()); + + // Variant 2 + variant2 = int8_t(1); + i8 = variant2; + CHECK_EQUAL(i8, variant2.get()); + + variant2 = uint8_t(2); + ui8 = variant2; + CHECK_EQUAL(ui8, variant2.get()); + + // Variant 3 + variant3 = int8_t(1); + i8 = variant3; + CHECK_EQUAL(i8, variant3.get()); + + variant3 = uint8_t(2); + ui8 = variant3; + CHECK_EQUAL(ui8, variant3.get()); + + variant3 = int16_t(3); + i16 = variant3; + CHECK_EQUAL(i16, variant3.get()); + + // Variant 4 + variant4 = int8_t(1); + i8 = variant4; + CHECK_EQUAL(i8, variant4.get()); + + variant4 = uint8_t(2); + ui8 = variant4; + CHECK_EQUAL(ui8, variant4.get()); + + variant4 = int16_t(3); + i16 = variant4; + CHECK_EQUAL(i16, variant4.get()); + + variant4 = uint16_t(4); + ui16 = variant4; + CHECK_EQUAL(ui16, variant4.get()); + + // Variant 5 + variant5 = int8_t(1); + i8 = variant5; + CHECK_EQUAL(i8, variant5.get()); + + variant5 = uint8_t(2); + ui8 = variant5; + CHECK_EQUAL(ui8, variant5.get()); + + variant5 = int16_t(3); + i16 = variant5; + CHECK_EQUAL(i16, variant5.get()); + + variant5 = uint16_t(4); + ui16 = variant5; + CHECK_EQUAL(ui16, variant5.get()); + + variant5 = int32_t(5); + i32 = variant5; + CHECK_EQUAL(i32, variant5.get()); + + // Variant 6 + variant6 = int8_t(1); + i8 = variant6; + CHECK_EQUAL(i8, variant6.get()); + + variant6 = uint8_t(2); + ui8 = variant6; + CHECK_EQUAL(ui8, variant6.get()); + + variant6 = int16_t(3); + i16 = variant6; + CHECK_EQUAL(i16, variant6.get()); + + variant6 = uint16_t(4); + ui16 = variant6; + CHECK_EQUAL(ui16, variant6.get()); + + variant6 = int32_t(5); + i32 = variant6; + CHECK_EQUAL(i32, variant6.get()); + + variant6 = uint32_t(6); + ui32 = variant6; + CHECK_EQUAL(ui32, variant6.get()); + + // Variant 7 + variant7 = int8_t(1); + i8 = variant7; + CHECK_EQUAL(i8, variant7.get()); + + variant7 = uint8_t(2); + ui8 = variant7; + CHECK_EQUAL(ui8, variant7.get()); + + variant7 = int16_t(3); + i16 = variant7; + CHECK_EQUAL(i16, variant7.get()); + + variant7 = uint16_t(4); + ui16 = variant7; + CHECK_EQUAL(ui16, variant7.get()); + + variant7 = int32_t(5); + i32 = variant7; + CHECK_EQUAL(i32, variant7.get()); + + variant7 = uint32_t(6); + ui32 = variant7; + CHECK_EQUAL(ui32, variant7.get()); + + variant7 = int64_t(7); + i64 = variant7; + CHECK_EQUAL(i64, variant7.get()); + + // Variant 8 + variant8 = int8_t(1); + i8 = variant8; + CHECK_EQUAL(i8, variant8.get()); + + variant8 = uint8_t(2); + ui8 = variant8; + CHECK_EQUAL(ui8, variant8.get()); + + variant8 = int16_t(3); + i16 = variant8; + CHECK_EQUAL(i16, variant8.get()); + + variant8 = uint16_t(4); + ui16 = variant8; + CHECK_EQUAL(ui16, variant8.get()); + + variant8 = int32_t(5); + i32 = variant8; + CHECK_EQUAL(i32, variant8.get()); + + variant8 = uint32_t(6); + ui32 = variant8; + CHECK_EQUAL(ui32, variant8.get()); + + variant8 = int64_t(7); + i64 = variant8; + CHECK_EQUAL(i64, variant8.get()); + + variant8 = uint64_t(8); + ui64 = variant8; + CHECK_EQUAL(ui64, variant8.get()); } //************************************************************************* TEST(TestConversionOperatorsConstReference) { - test_variant_1 variant; + test_variant_3a variant; variant = 1; const int& i = variant; CHECK_EQUAL(i, variant.get()); @@ -425,8 +610,8 @@ namespace //************************************************************************* TEST(TestSwap) { - test_variant_1 variant_1; - test_variant_1 variant_2; + test_variant_3a variant_1; + test_variant_3a variant_2; variant_1 = 1; variant_2 = std::string("Some Text"); @@ -440,7 +625,7 @@ namespace //************************************************************************* TEST(TestClear) { - test_variant_1 variant; + test_variant_3a variant; variant = 1; variant.clear(); From 4cad1308781576504d13bdd9c13e100515f54f9a Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 19:20:28 +0100 Subject: [PATCH 27/34] Added test_begin_empty & test_iterator --- test/test_pool.cpp | 70 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/test/test_pool.cpp b/test/test_pool.cpp index e1b90d5d..afbbbff2 100644 --- a/test/test_pool.cpp +++ b/test/test_pool.cpp @@ -229,6 +229,70 @@ namespace CHECK(!pool.is_in_pool(not_in_pool)); } + //************************************************************************* + TEST(test_begin_empty) + { + etl::pool pool; + + etl::pool::iterator it = pool.begin(); + CHECK(it == pool.end()); + + etl::pool::const_iterator cit = pool.begin(); + CHECK(cit == pool.end()); + + cit = pool.cbegin(); + CHECK(cit == pool.end()); + } + + //************************************************************************* + TEST(test_iterator) + { + etl::pool pool; + + std::set compare = { Test_Data2("0"), Test_Data2("2"), Test_Data2("4"), Test_Data2("6"), Test_Data2("8") }; + std::set test; + std::vector objects; + + // Build the set of objects. + objects.push_back(pool.allocate(Test_Data2("9"))); + objects.push_back(pool.allocate(Test_Data2("7"))); + objects.push_back(pool.allocate(Test_Data2("8"))); + objects.push_back(pool.allocate(Test_Data2("6"))); + objects.push_back(pool.allocate(Test_Data2("5"))); + objects.push_back(pool.allocate(Test_Data2("3"))); + objects.push_back(pool.allocate(Test_Data2("4"))); + objects.push_back(pool.allocate(Test_Data2("2"))); + objects.push_back(pool.allocate(Test_Data2("0"))); + objects.push_back(pool.allocate(Test_Data2("1"))); + + // Release "1", "3", "5", "7", "9". + pool.release(objects[0]); + pool.release(objects[1]); + pool.release(objects[4]); + pool.release(objects[5]); + pool.release(objects[9]); + + // Fill the test set with what we get from the iterator. + etl::pool::iterator i_pool = pool.begin(); + + while (i_pool != pool.end()) + { + test.insert(*i_pool); + ++i_pool; + } + + // Compare the results. + std::set::iterator i_compare = compare.begin(); + std::set::iterator i_test = test.begin(); + + CHECK_EQUAL(compare.size(), test.size()); + + while ((i_compare != compare.end()) && (i_test != test.end())) + { + CHECK_EQUAL(*i_compare++, *i_test++); + } + } + //************************************************************************* TEST(test_const_iterator) { @@ -290,10 +354,12 @@ namespace Test_Data* p2 = pool.allocate(); Pool::iterator i_data = pool.get_iterator(*p1); + Pool::iterator i_data2 = pool.get_iterator(*p2); Pool::iterator i_ndata = pool.get_iterator(not_in_pool); CHECK(p1 == &*i_data); CHECK(p2 != &*i_data); + CHECK(p2 == &*i_data2); CHECK(pool.end() == i_ndata); } @@ -308,11 +374,13 @@ namespace const Test_Data* p1 = pool.allocate(); const Test_Data* p2 = pool.allocate(); - Pool::const_iterator i_data = pool.get_iterator(*p1); + Pool::const_iterator i_data = pool.get_iterator(*p1); + Pool::const_iterator i_data2 = pool.get_iterator(*p2); Pool::const_iterator i_ndata = pool.get_iterator(not_in_pool); CHECK(p1 == &*i_data); CHECK(p2 != &*i_data); + CHECK(p2 == &*i_data2); CHECK(pool.end() == i_ndata); } }; From 97a7bb9d63f131e0b8b06defcd9d3f4effb15e51 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 19:21:17 +0100 Subject: [PATCH 28/34] Added test_at_exception, test_insert_value2 & test_at_exception --- test/test_map.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/test/test_map.cpp b/test/test_map.cpp index 6efb5272..b88ce7f8 100644 --- a/test/test_map.cpp +++ b/test/test_map.cpp @@ -333,6 +333,14 @@ namespace CHECK_EQUAL(data.at("9"), compare_data.at("9")); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_at_exception) + { + Data data(initial_data.begin(), initial_data.end()); + + CHECK_THROW(data.at("10"), etl::map_out_of_bounds); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_at_const) { @@ -351,6 +359,14 @@ namespace CHECK_EQUAL(data.at("9"), compare_data.at("9")); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_at_const_exception) + { + const Data data(initial_data.begin(), initial_data.end()); + + CHECK_THROW(data.at("10"), etl::map_out_of_bounds); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_assign_range) { @@ -415,6 +431,28 @@ namespace CHECK(isEqual); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_value2) + { + Compare_Data compare_data; + Data data; + + data.insert(Data::value_type(std::string("0"), 0)); + compare_data.insert(std::make_pair(std::string("0"), 0)); + + data.insert(Data::value_type(std::string("1"), 1)); + compare_data.insert(std::make_pair(std::string("1"), 1)); + + data.insert(Data::value_type(std::string("-1"), -1)); + compare_data.insert(std::make_pair(std::string("-1"), -1)); + + // Check that elements in map are the same + bool isEqual = Check_Equal(data.begin(), + data.end(), + compare_data.begin()); + CHECK(isEqual); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_insert_value_changed) { From c4097745553bd0cc917310c3a813ed65101ac939 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 19:21:34 +0100 Subject: [PATCH 29/34] Added many new tests --- test/test_list.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/test/test_list.cpp b/test/test_list.cpp index dd944b62..3586b739 100644 --- a/test/test_list.cpp +++ b/test/test_list.cpp @@ -575,6 +575,22 @@ namespace CHECK(are_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_pop_front_exception) + { + DataNDC data; + + CHECK_THROW(data.pop_front(), etl::list_empty); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_pop_back_exception) + { + DataNDC data; + + CHECK_THROW(data.pop_back(), etl::list_empty); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_erase_single) { @@ -764,6 +780,20 @@ namespace CHECK(are_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_unique_trivial) + { + CompareData compare_data; + DataNDC data; + + compare_data.unique(); + data.unique(); + + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + + CHECK(are_equal); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_remove) { @@ -820,6 +850,20 @@ namespace CHECK(are_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_sort_trivial) + { + CompareData compare_data; + DataNDC data; + + compare_data.sort(); + data.sort(); + + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + + CHECK(are_equal); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_splice_same) { @@ -1069,6 +1113,19 @@ namespace are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); + // Move to same place. + begin = data.begin(); + std::advance(begin, 2); + end = begin; + std::advance(end, 3); + to = data.begin(); + std::advance(to, 2); + + DataNDC data2(data); + data.splice(to, data, begin, end); + are_equal = std::equal(data.begin(), data.end(), data2.begin()); + CHECK(are_equal); + // Move to illegal place. begin = data.begin(); std::advance(begin, 2); @@ -1350,5 +1407,14 @@ namespace CHECK_EQUAL(data0.size(), compare0.size()); CHECK_EQUAL(data1.size(), compare1.size()); } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_merge_exception) + { + DataNDC2 data0(unsorted_data.begin(), unsorted_data.end()); + DataNDC2 data1(unsorted_data.begin(), unsorted_data.end()); + + CHECK_THROW(data0.merge(data1), etl::list_unsorted); + } }; } From d0a04614ef4dca0e470777102dc10185dc34de2e Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 19:21:59 +0100 Subject: [PATCH 30/34] Added to partition_point test --- test/test_algorithm.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/test_algorithm.cpp b/test/test_algorithm.cpp index 2fa70b68..91782b90 100644 --- a/test/test_algorithm.cpp +++ b/test/test_algorithm.cpp @@ -280,6 +280,12 @@ namespace int* partition1 = std::partition_point(std::begin(data1), std::end(data1), std::bind2nd(std::greater(), 4)); int* partition2 = etl::partition_point(std::begin(data1), std::end(data1), std::bind2nd(std::greater(), 4)); CHECK_EQUAL(std::distance(std::begin(data1), partition1), std::distance(std::begin(data1), partition2)); + + std::partition(std::begin(data1), std::end(data1), std::bind2nd(std::greater(), 8)); + + partition1 = std::partition_point(std::begin(data1), std::end(data1), std::bind2nd(std::greater(), 0)); + partition2 = etl::partition_point(std::begin(data1), std::end(data1), std::bind2nd(std::greater(), 0)); + CHECK_EQUAL(std::distance(std::begin(data1), partition1), std::distance(std::begin(data1), partition2)); } //========================================================================= From f1bb2ffe2f4255354ea183f6f742a6737d869094 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 21:16:43 +0100 Subject: [PATCH 31/34] Added debounce. --- test/vs2015/etl.vcxproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/vs2015/etl.vcxproj b/test/vs2015/etl.vcxproj index fce953d3..ad04aeae 100644 --- a/test/vs2015/etl.vcxproj +++ b/test/vs2015/etl.vcxproj @@ -169,6 +169,7 @@ + @@ -322,6 +323,7 @@ + false false From 0a98f6da729a55a13bc37852f60a347cdc940962 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 3 May 2016 21:17:20 +0100 Subject: [PATCH 32/34] Added debounce --- test/vs2015/etl.vcxproj.filters | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/vs2015/etl.vcxproj.filters b/test/vs2015/etl.vcxproj.filters index 5449213a..76e18a9c 100644 --- a/test/vs2015/etl.vcxproj.filters +++ b/test/vs2015/etl.vcxproj.filters @@ -492,6 +492,9 @@ Header Files + + ETL\Utilities + @@ -755,6 +758,9 @@ ETL\Utilities + + Source Files + From c74c31bd6ab497a31892250c97e0feefe1033a54 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 10 May 2016 19:09:47 +0100 Subject: [PATCH 33/34] Added signal & key debounce class --- examples/Debounce/Debounce.ino | 38 + examples/Debounce/Debounce.sln | 28 + examples/Debounce/Debounce.vcxproj | 126 +++ examples/Debounce/Debounce.vcxproj.filters | 25 + src/debounce.h | 530 +++++++++++++ test/test_debounce.cpp | 857 +++++++++++++++++++++ test/vs2015/etl.vcxproj | 2 - test/vs2015/etl.vcxproj.filters | 6 - 8 files changed, 1604 insertions(+), 8 deletions(-) create mode 100644 examples/Debounce/Debounce.ino create mode 100644 examples/Debounce/Debounce.sln create mode 100644 examples/Debounce/Debounce.vcxproj create mode 100644 examples/Debounce/Debounce.vcxproj.filters create mode 100644 src/debounce.h create mode 100644 test/test_debounce.cpp diff --git a/examples/Debounce/Debounce.ino b/examples/Debounce/Debounce.ino new file mode 100644 index 00000000..ca140f4a --- /dev/null +++ b/examples/Debounce/Debounce.ino @@ -0,0 +1,38 @@ +//*********************************************************************************** +// A debounce demo that reads a key and toggles the LED. +// Set the pin to the correct one for your key. +//*********************************************************************************** + +#include + +const int SAMPLE_TIME = 1; // The sample time in ms. +const int DEBOUNCE_COUNT = 50; // The number of samples that must agree before a key state change is recognised. 50 = 50ms for 1ms sample time. +const int HOLD_COUNT = 1000; // The number of samples that must agree before a key held state is recognised. 1000 = 1s for 1ms sample time. +const int REPEAT_COUNT = 200; // The number of samples that must agree before a key repeat state is recognised. 200 = 200ms for 1ms sample time. +const int KEY = XX; // The pin that the key is attached to. + +void setup() +{ + // Initialize LED pin as an output. + pinMode(LED_BUILTIN , OUTPUT); + + // Initialize KEY pin as an input. + pinMode(KEY, INPUT); +} + +void loop() +{ + static int led_state = LOW; + static etl::debounce key_state; + + if (key_state.add(digitalRead(KEY) == HIGH)) // Assumes 'HIGH' is 'pressed' and 'LOW' is 'released'. + { + if (key_state.is_set()) + { + led_state = (led_state == LOW ? HIGH : LOW); // Toggle the LED state on every validated press or repeat. + digitalWrite(LED_BUILTIN, led_state); + } + } + + delay(1); // Wait 1ms +} diff --git a/examples/Debounce/Debounce.sln b/examples/Debounce/Debounce.sln new file mode 100644 index 00000000..6d3f1698 --- /dev/null +++ b/examples/Debounce/Debounce.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25123.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Debounce", "Debounce.vcxproj", "{2D9F7027-A2E4-4558-869E-A09815D85E02}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2D9F7027-A2E4-4558-869E-A09815D85E02}.Debug|x64.ActiveCfg = Debug|x64 + {2D9F7027-A2E4-4558-869E-A09815D85E02}.Debug|x64.Build.0 = Debug|x64 + {2D9F7027-A2E4-4558-869E-A09815D85E02}.Debug|x86.ActiveCfg = Debug|Win32 + {2D9F7027-A2E4-4558-869E-A09815D85E02}.Debug|x86.Build.0 = Debug|Win32 + {2D9F7027-A2E4-4558-869E-A09815D85E02}.Release|x64.ActiveCfg = Release|x64 + {2D9F7027-A2E4-4558-869E-A09815D85E02}.Release|x64.Build.0 = Release|x64 + {2D9F7027-A2E4-4558-869E-A09815D85E02}.Release|x86.ActiveCfg = Release|Win32 + {2D9F7027-A2E4-4558-869E-A09815D85E02}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/examples/Debounce/Debounce.vcxproj b/examples/Debounce/Debounce.vcxproj new file mode 100644 index 00000000..e6162ff3 --- /dev/null +++ b/examples/Debounce/Debounce.vcxproj @@ -0,0 +1,126 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {2D9F7027-A2E4-4558-869E-A09815D85E02} + Debounce + 8.1 + + + + Application + true + v140 + MultiByte + + + Application + false + v140 + true + MultiByte + + + Application + true + v140 + MultiByte + + + Application + false + v140 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + + + Level3 + Disabled + true + C:\Users\John\AppData\Local\arduino15\packages\arduino\hardware\samd\1.6.5\cores\arduino;C:\Users\John\AppData\Local\arduino15\packages\arduino\hardware\samd\1.6.5\cores\arduino\avr;C:\Users\John\AppData\Local\arduino15\packages\arduino\hardware\samd\1.6.5\cores\arduino\USB;C:\Users\John\AppData\Local\arduino15\packages\arduino\hardware\samd\1.6.5\variants\arduino_zero;D:\Users\John\Documents\Programming\GitHub\etl\examples\Debounce;C:\Program Files (x86)\Arduino\libraries;C:\Users\John\AppData\Local\arduino15\packages\arduino\hardware\samd\1.6.5\libraries;C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\qdmsbpkv.c4h\Micro Platforms\default\debuggers;D:\Users\John\Documents\Programming\Arduino\libraries;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\CMSIS\4.0.0-atmel/CMSIS/Include/;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\CMSIS\4.0.0-atmel/Device/ATMEL/;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1\arm-none-eabi\include\c++\4.8.3;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1\arm-none-eabi\include\c++\4.8.3\arm-none-eabi;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1\arm-none-eabi\include\c++\4.8.3\bits;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1\arm-none-eabi\include;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1\arm-none-eabi\include\sys;C:\Users\John\AppData\Local\arduino15\packages\arduino\hardware\samd\1.6.5\system;C:\Users\John\AppData\Local\arduino15\packages\arduino\hardware\samd/avr;C:\Users\John\AppData\Local\arduino15\packages\arduino\hardware\samd/usb;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1\lib\gcc\arm-none-eabi\4.8.3\include;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\CMSIS\4.0.0-atmel;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\CMSIS\4.0.0-atmel\Device\ATMEL\samd21\include;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\CMSIS\4.0.0-atmel\CMSIS\include;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\CMSIS\4.0.0-atmel\Device\ATMEL\samd21\include\component;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\CMSIS\4.0.0-atmel\Device\ATMEL\samd21\include\instance;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\CMSIS\4.0.0-atmel\Device\ATMEL\samd21\include\pio;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\CMSIS\4.0.0-atmel\Device\ATMEL\samd21\include\component;%(AdditionalIncludeDirectories) + D:\Users\John\Documents\Programming\GitHub\etl\examples\Debounce\__vm\.Debounce.vsarduino.h;%(ForcedIncludeFiles) + F_CPU=48000000L;ARDUINO=10607;ARDUINO_SAMD_ZERO;ARDUINO_ARCH_SAMD;__SAMD21G18A__;USB_VID=0x2341;USB_PID=0x804d;USBCON;__cplusplus=201103L;%(PreprocessorDefinitions) + + + + + Level3 + Disabled + true + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + + + + + CppCode + + + + + + + + + \ No newline at end of file diff --git a/examples/Debounce/Debounce.vcxproj.filters b/examples/Debounce/Debounce.vcxproj.filters new file mode 100644 index 00000000..ac927ede --- /dev/null +++ b/examples/Debounce/Debounce.vcxproj.filters @@ -0,0 +1,25 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + Header Files + + + \ No newline at end of file diff --git a/src/debounce.h b/src/debounce.h new file mode 100644 index 00000000..b0165c47 --- /dev/null +++ b/src/debounce.h @@ -0,0 +1,530 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +http://www.etlcpp.com + +Copyright(c) 2016 jwellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#ifndef __ETL_DEBOUNCE__ +#define __ETL_DEBOUNCE__ + +#include + +#include "static_assert.h" + +namespace etl +{ + namespace __private_debounce__ + { + class debounce_base + { + public: + + void add(bool sample) + { + state &= ~CHANGED; + + // Changed from last time? + if (sample != bool((state & LAST) != 0)) + { + count = START_COUNT; + } + } + + //************************************************************************* + /// Gets the current debouncer change state. + ///\return 'true' if the debouncer has changed state. + //************************************************************************* + bool has_changed() const + { + return (state & CHANGED) != 0; + } + + //************************************************************************* + /// Gets the current debouncer state. + ///\return 'true' if the debouncer is in the true state. + //************************************************************************* + bool is_set() const + { + return (state & CURRENT) != 0; + } + + //************************************************************************* + /// Gets the debouncer hold state. + ///\return 'true' if the debouncer is in the hold state. + //************************************************************************* + bool is_held() const + { + return (state & HELD) != 0; + } + + //************************************************************************* + /// Gets the debouncer repeat state. + ///\return 'true' if the debouncer is repeating. + //************************************************************************* + bool is_repeating() const + { + return (state & REPEATING) != 0; + } + + protected: + + //************************************************************************* + /// Constructor. + ///\param initial_state The initial state. Default = false. + //************************************************************************* + debounce_base(bool initial_state = false) + : state(initial_state ? (CURRENT | LAST) : 0), + count(START_COUNT) + { + } + + enum + { + START_COUNT = 0 + }; + + enum + { + CURRENT = 1, + LAST = 2, + HELD = 4, + CHANGED = 8, + REPEATING = 16 + }; + + uint8_t state; + + /// The state count. + int16_t count; + }; + } + + //*************************************************************************** + /// A class to debounce signals. + /// The state is decided over N samples, defined by the VALID_COUNT value. + /// If the samples are consistent for VALID_COUNT times then the debouncer state is defined. + /// If the samples change then the debouncer will change state after VALID_COUNT samples. + /// If the samples are true for a count of HOLD_COUNT then the debouncer input is 'held'. + /// The debouncer may be constructed in either state. + //*************************************************************************** + template + class debounce : public __private_debounce__::debounce_base + { + private: + + enum + { + VALID_THRESHOLD = VALID_COUNT, + HOLD_THRESHOLD = VALID_THRESHOLD + HOLD_COUNT, + REPEAT_THRESHOLD = HOLD_THRESHOLD + REPEAT_COUNT, + }; + + using debounce_base::add; + + public: + + //************************************************************************* + /// Constructor. + ///\param initial_state The initial state. Default = false. + //************************************************************************* + debounce(bool initial_state = false) + : debounce_base(initial_state) + { + } + + //************************************************************************* + /// Adds a new sample. + /// Returns 'true' if the debouncer changes state from... + /// 1. Clear to Set. + /// 2. Set to Clear. + /// 3. Not Held to Held. + /// 4. Key repeats. + ///\param sample The new sample. + ///\return 'true' if the debouncer changed state. + //************************************************************************* + bool add(bool sample) + { + debounce_base::add(sample); + + if (sample) + { + // Set sample. + if (count < REPEAT_THRESHOLD) + { + ++count; + + if (count == VALID_THRESHOLD) + { + // Set. + state |= CHANGED; + state |= CURRENT; + } + else if (count == HOLD_THRESHOLD) + { + // Held. + state |= CHANGED; + state |= HELD; + } + else if (count == REPEAT_THRESHOLD) + { + // Repeat. + state |= CHANGED; + state |= REPEATING; + count = HOLD_THRESHOLD; + } + } + } + else + { + // Clear sample. + if (count > -VALID_THRESHOLD) + { + --count; + + if (count == -VALID_THRESHOLD) + { + // Clear. + state |= CHANGED; + state &= ~CURRENT; + state &= ~HELD; + state &= ~REPEATING; + } + } + } + + if (sample) + { + state |= LAST; + } + else + { + state &= ~LAST; + } + + return (state & CHANGED) != 0; + } + }; + + template + class debounce : public __private_debounce__::debounce_base + { + private: + + enum + { + VALID_THRESHOLD = VALID_COUNT, + HOLD_THRESHOLD = VALID_THRESHOLD + HOLD_COUNT + }; + + using debounce_base::add; + + public: + + //************************************************************************* + /// Constructor. + ///\param initial_state The initial state. Default = false. + //************************************************************************* + debounce(bool initial_state = false) + : debounce_base(initial_state) + { + } + + //************************************************************************* + /// Adds a new sample. + /// Returns 'true' if the debouncer changes state from... + /// 1. Clear to Set. + /// 2. Set to Clear. + /// 3. Not Held to Held. + ///\param sample The new sample. + ///\return 'true' if the debouncer changed state. + //************************************************************************* + bool add(bool sample) + { + debounce_base::add(sample); + + if (sample) + { + // Set sample. + if (count < HOLD_THRESHOLD) + { + ++count; + + if (count == VALID_THRESHOLD) + { + // Set. + state |= CHANGED; + state |= CURRENT; + } + else if (count == HOLD_THRESHOLD) + { + // Held. + state |= CHANGED; + state |= HELD; + } + } + } + else + { + // Clear sample. + if (count > -VALID_THRESHOLD) + { + --count; + + if (count == -VALID_THRESHOLD) + { + // Clear. + state |= CHANGED; + state &= ~CURRENT; + state &= ~HELD; + } + } + } + + if (sample) + { + state |= LAST; + } + else + { + state &= ~LAST; + } + + return (state & CHANGED) != 0; + } + }; + + template + class debounce : public __private_debounce__::debounce_base + { + private: + + enum + { + VALID_THRESHOLD = VALID_COUNT, + }; + + using debounce_base::add; + + public: + + //************************************************************************* + /// Constructor. + ///\param initial_state The initial state. Default = false. + //************************************************************************* + debounce(bool initial_state = false) + : debounce_base(initial_state) + { + } + + //************************************************************************* + /// Adds a new sample. + /// Returns 'true' if the debouncer changes state from... + /// 1. Clear to Set. + /// 2. Set to Clear. + ///\param sample The new sample. + ///\return 'true' if the debouncer changed state. + //************************************************************************* + bool add(bool sample) + { + debounce_base::add(sample); + + if (sample) + { + // Set sample. + if (count < VALID_THRESHOLD) + { + ++count; + + if (count == VALID_THRESHOLD) + { + // Set. + state |= CHANGED; + state |= CURRENT; + } + } + } + else + { + // Clear sample. + if (count > -VALID_THRESHOLD) + { + --count; + + if (count == -VALID_THRESHOLD) + { + // Clear. + state |= CHANGED; + state &= ~CURRENT; + } + } + } + + if (sample) + { + state |= LAST; + } + else + { + state &= ~LAST; + } + + return (state & CHANGED) != 0; + } + }; + + template <> + class debounce<0, 0, 0> : public __private_debounce__::debounce_base + { + public: + + using debounce_base::add; + + //************************************************************************* + /// Constructor. + ///\param initial_state The initial state. Default = false. + //************************************************************************* + debounce() + : debounce_base(false), + valid_threshold(1), + hold_threshold(0), + repeat_threshold(0) + { + } + + //************************************************************************* + /// Constructor. + ///\param initial_state The initial state. + ///\param valid_count The count for a valid state. Default = 1. + ///\param hold_count The count after valid_count for a hold state. Default = 0. + ///\param repeat_count The count after hold_count for a key repeat. Default = 0. + //************************************************************************* + debounce(bool initial_state, uint16_t valid_count = 1, uint16_t hold_count = 0, uint16_t repeat_count = 0) + : debounce_base(initial_state) + { + set(valid_count, hold_count, repeat_count); + } + + //************************************************************************* + /// Constructor. + ///\param initial_state The initial state. Default = false. + //************************************************************************* + void set(uint16_t valid_count, uint16_t hold_count = 0, uint16_t repeat_count = 0) + { + valid_threshold = valid_count; + hold_threshold = valid_threshold + hold_count; + repeat_threshold = hold_threshold + repeat_count; + } + + //************************************************************************* + /// Adds a new sample. + /// Returns 'true' if the debouncer changes state from... + /// 1. Clear to Set. + /// 2. Set to Clear. + /// 3. Not Held to Held. + /// 4. Key repeats. + ///\param sample The new sample. + ///\return 'true' if the debouncer changed state. + //************************************************************************* + bool add(bool sample) + { + debounce_base::add(sample); + + if (sample) + { + // Set sample. + if (count < repeat_threshold) + { + ++count; + + if (count == valid_threshold) + { + // Set. + state |= CHANGED; + state |= CURRENT; + } + + if (hold_threshold != valid_threshold) + { + if (count == hold_threshold) + { + // Held. + state |= CHANGED; + state |= HELD; + } + } + + if (repeat_threshold != hold_threshold) + { + if (count == repeat_threshold) + { + // Repeat. + state |= CHANGED; + state |= REPEATING; + count = hold_threshold; + } + } + } + } + else + { + // Clear sample. + if (count > -valid_threshold) + { + --count; + + if (count == -valid_threshold) + { + // Clear. + state |= CHANGED; + state &= ~CURRENT; + state &= ~HELD; + state &= ~REPEATING; + } + } + } + + if (sample) + { + state |= LAST; + } + else + { + state &= ~LAST; + } + + return (state & CHANGED) != 0; + } + + private: + + uint16_t valid_threshold; + uint16_t hold_threshold; + uint16_t repeat_threshold; + }; +} + +#endif diff --git a/test/test_debounce.cpp b/test/test_debounce.cpp new file mode 100644 index 00000000..08d6816f --- /dev/null +++ b/test/test_debounce.cpp @@ -0,0 +1,857 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +http://www.etlcpp.com + +Copyright(c) 2016 jwellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#include + +#include "../src/debounce.h" + +namespace +{ + SUITE(test_debounce) + { + TEST(test_debounce_default_4_0_0_nonbounce) + { + etl::debounce<4, 8, 0> key_state; + + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + //******************************* + // Transition to set. + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + // Valid set. + CHECK(key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + //******************************* + // Transition to clear. + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + // Valid clear. + CHECK(key_state.add(false)); + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + } + + //************************************************************************* + TEST(test_debounce_default_4_4_0_nonbounce) + { + etl::debounce<4, 4, 0> key_state; + + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + //******************************* + // Transition to set. + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + // Valid set. + CHECK(key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + //******************************* + // Transition to held. + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + // Valid held. + CHECK(key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(!key_state.is_repeating()); + + //******************************* + // No transition to repeating. + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(!key_state.is_repeating()); + + //******************************* + // Transition to clear. + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(!key_state.is_repeating()); + + // Valid clear. + CHECK(key_state.add(false)); + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + } + + //************************************************************************* + TEST(test_debounce_default_4_4_3_nonbounce) + { + etl::debounce<4, 4, 3> key_state; + + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + //******************************* + // Transition to set. + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + // Valid set. + CHECK(key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + //******************************* + // Transition to held. + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + // Valid held. + CHECK(key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(!key_state.is_repeating()); + + //******************************* + // Transition to repeating. + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(!key_state.is_repeating()); + + // Valid repeat. + CHECK(key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(key_state.is_repeating()); + + // Valid repeat. + CHECK(key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(key_state.is_repeating()); + + //******************************* + // Transition to clear. + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(key_state.is_repeating()); + + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(key_state.is_repeating()); + + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(key_state.is_repeating()); + + // Valid clear. + CHECK(key_state.add(false)); + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + } + + //************************************************************************* + TEST(test_debounce_initial_set_4_4_0_nonbounce) + { + etl::debounce<4, 4> key_state(true); + + CHECK(key_state.is_set()); + + //******************************* + // Transition to clear. + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + + CHECK(key_state.add(false)); + CHECK(!key_state.is_set()); + + //******************************* + // Transition to set. + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + + CHECK(key_state.add(true)); + CHECK(key_state.is_set()); + } + + //************************************************************************* + TEST(test_debounce_default_4_4_0_bounce) + { + etl::debounce<4, 4> key_state; + + CHECK(!key_state.is_set()); + + //******************************* + // Transition to set. + // Bounce 1 + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + + CHECK(!key_state.add(false)); + CHECK(!key_state.is_set()); + + // Bounce 2 + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + + CHECK(!key_state.add(false)); + CHECK(!key_state.is_set()); + + // Bounce 3 + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + + CHECK(!key_state.add(false)); + CHECK(!key_state.is_set()); + + // Stopped bouncing + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + + // Valid set. + CHECK(key_state.add(true)); + CHECK(key_state.is_set()); + + //******************************* + // Transition to clear. + // Bounce 1 + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + + // Bounce 2 + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + + // Bounce 3 + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + + // Stopped bouncing + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + + // Valid clear. + CHECK(key_state.add(false)); + CHECK(!key_state.is_set()); + } + + TEST(test_debounce_default_4_0_0_nonbounce_variables) + { + etl::debounce<> key_state; + + key_state.set(4); + + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + //******************************* + // Transition to set. + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + // Valid set. + CHECK(key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + //******************************* + // Transition to clear. + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + // Valid clear. + CHECK(key_state.add(false)); + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + } + + //************************************************************************* + TEST(test_debounce_default_4_4_0_nonbounce_variables) + { + etl::debounce<> key_state; + + key_state.set(4, 4); + + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + //******************************* + // Transition to set. + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + // Valid set. + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + //******************************* + // Transition to held. + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + // Valid held. + CHECK(key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(!key_state.is_repeating()); + + //******************************* + // No transition to repeating. + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(!key_state.is_repeating()); + + //******************************* + // Transition to clear. + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(!key_state.is_repeating()); + + // Valid clear. + CHECK(key_state.add(false)); + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + } + + //************************************************************************* + TEST(test_debounce_default_4_4_3_nonbounce_variables) + { + etl::debounce<> key_state; + + key_state.set(4, 4, 3); + + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + //******************************* + // Transition to set. + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + // Valid set. + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + //******************************* + // Transition to held. + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + + // Valid held. + CHECK(key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(!key_state.is_repeating()); + + //******************************* + // Transition to repeating. + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(!key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(!key_state.is_repeating()); + + // Valid repeat. + CHECK(key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(key_state.is_repeating()); + + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(key_state.is_repeating()); + + // Valid repeat. + CHECK(key_state.add(true)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(key_state.is_repeating()); + + //******************************* + // Transition to clear. + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(key_state.is_repeating()); + + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(key_state.is_repeating()); + + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + CHECK(key_state.is_held()); + CHECK(key_state.is_repeating()); + + // Valid clear. + CHECK(key_state.add(false)); + CHECK(!key_state.is_set()); + CHECK(!key_state.is_held()); + CHECK(!key_state.is_repeating()); + } + + //************************************************************************* + TEST(test_debounce_initial_set_4_4_0_nonbounce_variables) + { + etl::debounce<> key_state(true); + + key_state.set(4, 4); + + CHECK(key_state.is_set()); + + //******************************* + // Transition to clear. + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + + CHECK(key_state.add(false)); + CHECK(!key_state.is_set()); + + //******************************* + // Transition to set. + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + + CHECK(key_state.add(true)); + CHECK(key_state.is_set()); + } + + //************************************************************************* + TEST(test_debounce_default_4_4_0_bounce_variables) + { + etl::debounce<> key_state; + + key_state.set(4, 4); + + CHECK(!key_state.is_set()); + + //******************************* + // Transition to set. + // Bounce 1 + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + + CHECK(!key_state.add(false)); + CHECK(!key_state.is_set()); + + // Bounce 2 + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + + CHECK(!key_state.add(false)); + CHECK(!key_state.is_set()); + + // Bounce 3 + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + + CHECK(!key_state.add(false)); + CHECK(!key_state.is_set()); + + // Stopped bouncing + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + + CHECK(!key_state.add(true)); + CHECK(!key_state.is_set()); + + // Valid set. + CHECK(key_state.add(true)); + CHECK(key_state.is_set()); + + //******************************* + // Transition to clear. + // Bounce 1 + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + + // Bounce 2 + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + + // Bounce 3 + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + + CHECK(!key_state.add(true)); + CHECK(key_state.is_set()); + + // Stopped bouncing + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + + CHECK(!key_state.add(false)); + CHECK(key_state.is_set()); + + // Valid clear. + CHECK(key_state.add(false)); + CHECK(!key_state.is_set()); + } + }; +} diff --git a/test/vs2015/etl.vcxproj b/test/vs2015/etl.vcxproj index ad04aeae..3797c060 100644 --- a/test/vs2015/etl.vcxproj +++ b/test/vs2015/etl.vcxproj @@ -215,7 +215,6 @@ - @@ -266,7 +265,6 @@ - diff --git a/test/vs2015/etl.vcxproj.filters b/test/vs2015/etl.vcxproj.filters index 76e18a9c..27792ec3 100644 --- a/test/vs2015/etl.vcxproj.filters +++ b/test/vs2015/etl.vcxproj.filters @@ -477,15 +477,9 @@ ETL\Containers - - ETL\Containers - ETL\Private - - ETL\Containers - Header Files From 434ec0720943226e4d1a0a4a91286ccbe14ec53a Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 10 May 2016 19:13:10 +0100 Subject: [PATCH 34/34] Updated to 8.0.4 to include new debounce class. --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index e0e13cc2..17e40247 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Embedded Template Library -version=8.0.3 +version=8.0.4 author= John Wellbelove maintainer=John Wellbelove sentence=A C++ template library tailored for embedded systems.