From d58f675722f190bbb9395b496c85e3c4fd72e185 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 28 Dec 2016 12:40:29 +0000 Subject: [PATCH] Added hash functions --- src/callback.h | 6 +- src/fnv_1.h | 28 +-- src/hash.h | 60 +++-- src/ibasic_string.h | 6 +- src/iforward_list.h | 30 +-- src/intrusive_forward_list.h | 30 +-- src/intrusive_links.h | 3 +- src/intrusive_list.h | 2 +- src/ipriority_queue.h | 10 +- src/iqueue.h | 2 +- src/istack.h | 2 +- src/ivector.h | 2 +- src/pearson.cpp | 1 - src/private/ivectorpointer.h | 47 +++- src/private/map_base.h | 28 +-- src/private/pvoidvector.h | 16 +- src/string.h | 17 +- src/type_def.h | 42 +--- src/type_traits.h | 46 ++-- src/u16string.h | 17 +- src/u32string.h | 17 +- src/variant.h | 71 ++++-- src/wstring.h | 17 +- test/test_intrusive_forward_list.cpp | 343 +++++---------------------- test/test_intrusive_links.cpp | 7 +- test/test_variant.cpp | 16 ++ test/vs2015/etl.vcxproj | 16 +- test/vs2015/etl.vcxproj.filters | 6 - 28 files changed, 353 insertions(+), 535 deletions(-) diff --git a/src/callback.h b/src/callback.h index 0111c492..805e3bec 100644 --- a/src/callback.h +++ b/src/callback.h @@ -28,8 +28,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ -#error In Development. Do not use. - #ifndef __ETL_CALLBACK__ #define __ETL_CALLBACK__ @@ -37,8 +35,8 @@ namespace etl { //*************************************************************************** /// A callback class designed to be multiply inherited by other client classes. - /// The class is parameterised with a callback parameter type and a unique id. - /// The unique id allows muliple callbacks with the same parameter type. + /// The class is parametrised with a callback parameter type and a unique id. + /// The unique id allows multiple callbacks with the same parameter type. ///\tparam TParameter The callback parameter type. ///\tparam ID The unique id for this callback. //*************************************************************************** diff --git a/src/fnv_1.h b/src/fnv_1.h index ce787651..c9799196 100644 --- a/src/fnv_1.h +++ b/src/fnv_1.h @@ -106,17 +106,17 @@ namespace etl this->add(begin, end); } }; - + //*************************************************************************** /// fnv_1a policy. /// Calculates FNV1A. //*************************************************************************** struct fnv_1a_policy_64 - { + { typedef uint64_t value_type; inline uint64_t initial() const - { + { return OFFSET_BASIS; } @@ -124,7 +124,7 @@ namespace etl { hash ^= value; hash *= PRIME; - return hash; + return hash; } inline uint64_t final(uint64_t hash) const @@ -135,7 +135,7 @@ namespace etl static const uint64_t OFFSET_BASIS = 0xCBF29CE484222325; static const uint64_t PRIME = 0x00000100000001b3; }; - + //*************************************************************************** /// Calculates the fnv_1a_64 hash. ///\ingroup fnv_1a_64 @@ -170,11 +170,11 @@ namespace etl /// Calculates FNV1. //*************************************************************************** struct fnv_1_policy_32 - { - typedef uint32_t value_type; - - inline uint32_t initial() const { + typedef uint32_t value_type; + + inline uint32_t initial() const + { return OFFSET_BASIS; } @@ -182,7 +182,7 @@ namespace etl { hash *= PRIME; hash ^= value; - return hash; + return hash; } inline uint32_t final(uint32_t hash) const @@ -222,17 +222,17 @@ namespace etl this->add(begin, end); } }; - + //*************************************************************************** /// fnv_1a policy. /// Calculates FNV1A. //*************************************************************************** struct fnv_1a_policy_32 - { + { typedef uint32_t value_type; inline uint32_t initial() const - { + { return OFFSET_BASIS; } @@ -240,7 +240,7 @@ namespace etl { hash ^= value; hash *= PRIME; - return hash; + return hash; } inline uint32_t final(uint32_t hash) const diff --git a/src/hash.h b/src/hash.h index 2a3f8ddc..39408f3a 100644 --- a/src/hash.h +++ b/src/hash.h @@ -50,9 +50,9 @@ namespace etl /// Hash to use when size_t is 16 bits. /// T is always expected to be size_t. //************************************************************************* - template + template typename enable_if::type - generic_hash(uint8_t* begin, uint8_t* end) + generic_hash(const uint8_t* begin, const uint8_t* end) { uint32_t h = fnv_1a_32(begin, end); @@ -63,9 +63,9 @@ namespace etl /// Hash to use when size_t is 32 bits. /// T is always expected to be size_t. //************************************************************************* - template + template typename enable_if::type - generic_hash(uint8_t* begin, uint8_t* end) + generic_hash(const uint8_t* begin, const uint8_t* end) { return fnv_1a_32(begin, end); } @@ -74,9 +74,9 @@ namespace etl /// Hash to use when size_t is 64 bits. /// T is always expected to be size_t. //************************************************************************* - template + template typename enable_if::type - generic_hash(uint8_t* begin, uint8_t* end) + generic_hash(const uint8_t* begin, const uint8_t* end) { return fnv_1a_64(begin, end); } @@ -323,9 +323,15 @@ namespace etl // If it's the same size as a size_t. if (sizeof(size_t) == sizeof(v)) { - size_t t; - memcpy(&t, &v, sizeof(size_t)); - return t; + union + { + size_t s; + float v; + } u; + + u.v = v; + + return u.s; } else { @@ -347,9 +353,15 @@ namespace etl // If it's the same size as a size_t. if (sizeof(size_t) == sizeof(v)) { - size_t t; - memcpy(&t, &v, sizeof(size_t)); - return t; + union + { + size_t s; + double v; + } u; + + u.v = v; + + return u.s; } else { @@ -371,9 +383,15 @@ namespace etl // If it's the same size as a size_t. if (sizeof(size_t) == sizeof(v)) { - size_t t; - memcpy(&t, &v, sizeof(size_t)); - return t; + union + { + size_t s; + long double v; + } u; + + u.v = v; + + return u.s; } else { @@ -395,9 +413,15 @@ namespace etl // If it's the same size as a size_t. if (sizeof(size_t) == sizeof(T*)) { - size_t t; - memcpy(&t, &v, sizeof(size_t)); - return t; + union + { + size_t s; + const T* v; + } u; + + u.v = v; + + return u.s; } else { diff --git a/src/ibasic_string.h b/src/ibasic_string.h index 34c6ba95..85bd6d9c 100644 --- a/src/ibasic_string.h +++ b/src/ibasic_string.h @@ -36,7 +36,7 @@ SOFTWARE. #include #include #include -#include +#include #include "private/string_base.h" #include "platform.h" @@ -460,7 +460,7 @@ namespace etl //************************************************************************* /// Removes an element from the end of the string. - /// Undefined behaviour if the string is empty. + /// Does nothing if the string is empty. //************************************************************************* void pop_back() { @@ -468,7 +468,7 @@ namespace etl ETL_ASSERT(!empty(), ETL_ERROR(string_empty)); #endif - p_buffer[--current_size] = 0; + p_buffer[--current_size] = 0; } //********************************************************************* diff --git a/src/iforward_list.h b/src/iforward_list.h index 0f418209..b663ad8e 100644 --- a/src/iforward_list.h +++ b/src/iforward_list.h @@ -256,7 +256,7 @@ namespace etl const Node* p_node; }; - typedef typename std::iterator_traits::difference_type difference_type; + typedef typename std::iterator_traits::difference_type difference_type; //************************************************************************* /// Gets the beginning of the forward_list. @@ -348,7 +348,7 @@ namespace etl //************************************************************************* /// Assigns a range of values to the forward_list. - /// If asserts or exceptions are enabled throws etl::forward_list_full if the forward_list does not have enough free space. + /// If asserts or exceptions are enabled throws etl::forward_list_full if the forward_list does not have enough free space. /// If ETL_THROW_EXCEPTIONS & _DEBUG are defined throws forward_list_iterator if the iterators are reversed. //************************************************************************* template @@ -707,7 +707,7 @@ namespace etl if (is_trivial_list()) { - return; + return; } while (true) @@ -746,32 +746,32 @@ namespace etl // Decide whether the next node of merge comes from left or right. if (left_size == 0) { - // Left is empty. The node must come from right. - p_node = p_right; + // Left is empty. The node must come from right. + p_node = p_right; ++p_right; --right_size; - } + } else if (right_size == 0 || p_right == end()) { - // Right is empty. The node must come from left. - p_node = p_left; + // Right is empty. The node must come from left. + p_node = p_left; ++p_left; --left_size; - } + } else if (compare(*p_left, *p_right)) { - // First node of left is lower or same. The node must come from left. - p_node = p_left; + // First node of left is lower or same. The node must come from left. + p_node = p_left; ++p_left; --left_size; - } + } else { - // First node of right is lower. The node must come from right. - p_node = p_right; + // First node of right is lower. The node must come from right. + p_node = p_right; ++p_right; --right_size; - } + } // Add the next node to the merged head. if (p_head == before_begin()) diff --git a/src/intrusive_forward_list.h b/src/intrusive_forward_list.h index 3bec7fd4..fa275352 100644 --- a/src/intrusive_forward_list.h +++ b/src/intrusive_forward_list.h @@ -325,7 +325,7 @@ namespace etl const value_type* p_value; }; - typedef typename std::iterator_traits::difference_type difference_type; + typedef typename std::iterator_traits::difference_type difference_type; //************************************************************************* /// Constructor. @@ -659,7 +659,7 @@ namespace etl if (is_trivial_list()) { - return; + return; } while (true) @@ -698,32 +698,32 @@ namespace etl // Decide whether the next link of merge comes from left or right. if (left_size == 0) { - // Left is empty. The link must come from right. - i_link = i_right; + // Left is empty. The link must come from right. + i_link = i_right; ++i_right; --right_size; - } + } else if (right_size == 0 || i_right == end()) { - // Right is empty. The link must come from left. - i_link = i_left; + // Right is empty. The link must come from left. + i_link = i_left; ++i_left; --left_size; - } + } else if (compare(*i_left, *i_right)) { - // First link of left is lower or same. The link must come from left. - i_link = i_left; + // First link of left is lower or same. The link must come from left. + i_link = i_left; ++i_left; --left_size; - } + } else { - // First link of right is lower. The link must come from right. - i_link = i_right; + // First link of right is lower. The link must come from right. + i_link = i_right; ++i_right; --right_size; - } + } // Add the next link to the merged head. if (i_head == before_begin()) @@ -906,7 +906,7 @@ namespace etl last = last->link_type::etl_next; } - // Unlink from the source other. + // Unlink from the source list. link_type* first_next = first->link_type::etl_next; etl::unlink_after(*first, *last); diff --git a/src/intrusive_links.h b/src/intrusive_links.h index eb0bf522..823a6dc2 100644 --- a/src/intrusive_links.h +++ b/src/intrusive_links.h @@ -149,7 +149,7 @@ namespace etl struct forward_link; //****************************************************************** - // Specialisation for checked link option. + // Specialisation for checked unlink option. // An error will be generated if the links are valid when the object // is destroyed. //****************************************************************** @@ -669,7 +669,6 @@ namespace etl { clear(); } - void clear() { etl_parent = nullptr; diff --git a/src/intrusive_list.h b/src/intrusive_list.h index 9e151c8f..2da75417 100644 --- a/src/intrusive_list.h +++ b/src/intrusive_list.h @@ -342,7 +342,7 @@ namespace etl const value_type* p_value; }; - typedef typename std::iterator_traits::difference_type difference_type; + typedef typename std::iterator_traits::difference_type difference_type; //************************************************************************* /// Constructor. diff --git a/src/ipriority_queue.h b/src/ipriority_queue.h index 74a11cfd..8e58300a 100644 --- a/src/ipriority_queue.h +++ b/src/ipriority_queue.h @@ -180,14 +180,14 @@ namespace etl //************************************************************************* /// Removes the oldest value from the back of the priority queue. - /// Undefined behaviour if the priority queue is already empty. + /// Does nothing if the priority queue is already empty. //************************************************************************* void pop() { - // Move largest element to end - std::pop_heap(container.begin(), container.end(), TCompare()); - // Actually remove largest element at end - container.pop_back(); + // Move largest element to end + std::pop_heap(container.begin(), container.end(), TCompare()); + // Actually remove largest element at end + container.pop_back(); } //************************************************************************* diff --git a/src/iqueue.h b/src/iqueue.h index 8d8751f2..0f55963c 100644 --- a/src/iqueue.h +++ b/src/iqueue.h @@ -162,7 +162,7 @@ namespace etl //************************************************************************* /// Removes the oldest value from the back of the queue. - /// Undefined behaviour if the queue is already empty. + /// Does nothing if the queue is already empty. //************************************************************************* void pop() { diff --git a/src/istack.h b/src/istack.h index d742f452..35e8107c 100644 --- a/src/istack.h +++ b/src/istack.h @@ -135,7 +135,7 @@ namespace etl //************************************************************************* /// Removes the oldest item from the top of the stack. - /// Undefined behaviour if the stack is already empty. + /// Does nothing if the stack is already empty. //************************************************************************* void pop() { diff --git a/src/ivector.h b/src/ivector.h index a186a4a7..0dfe8491 100644 --- a/src/ivector.h +++ b/src/ivector.h @@ -475,7 +475,7 @@ namespace etl //************************************************************************* /// Removes an element from the end of the vector. - /// Undefined behaviour if the vector is empty. + /// Does nothing if the vector is empty. //************************************************************************* void pop_back() { diff --git a/src/pearson.cpp b/src/pearson.cpp index a10940b4..94c5ec0f 100644 --- a/src/pearson.cpp +++ b/src/pearson.cpp @@ -61,4 +61,3 @@ namespace etl 213, 163, 150, 101, 129, 14, 249, 205, 214, 1, 41, 56, 162, 72, 239, 82 } ; } - diff --git a/src/private/ivectorpointer.h b/src/private/ivectorpointer.h index 13c4512b..1aae4e5c 100644 --- a/src/private/ivectorpointer.h +++ b/src/private/ivectorpointer.h @@ -35,7 +35,7 @@ SOFTWARE. #error This header is a private element of etl::ivector #endif -#include "private/pvoidvector.h" +#include "pvoidvector.h" namespace etl { @@ -456,7 +456,7 @@ namespace etl template bool operator ==(const etl::ivector& lhs, const etl::ivector& rhs) { - return (lhs.size() == rhs.size()) && std::equal(lhs.begin(), lhs.end(), rhs.begin()); + return pvoidvector_equal(lhs, rhs); } //*************************************************************************** @@ -469,7 +469,7 @@ namespace etl template bool operator !=(const etl::ivector& lhs, const etl::ivector& rhs) { - return !(lhs == rhs); + return pvoidvector_not_equal(lhs, rhs); } //*************************************************************************** @@ -482,7 +482,7 @@ namespace etl template bool operator <(const etl::ivector& lhs, const etl::ivector& rhs) { - return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); + return pvoidvector_less_than(lhs, rhs); } //*************************************************************************** @@ -495,7 +495,7 @@ namespace etl template bool operator >(const etl::ivector& lhs, const etl::ivector& rhs) { - return (rhs < lhs); + return pvoidvector_greater_than(lhs, rhs); } //*************************************************************************** @@ -508,7 +508,7 @@ namespace etl template bool operator <=(const etl::ivector& lhs, const etl::ivector& rhs) { - return !(lhs > rhs); + return pvoidvector_less_than_equal(lhs, rhs); } //*************************************************************************** @@ -521,7 +521,40 @@ namespace etl template bool operator >=(const etl::ivector& lhs, const etl::ivector& rhs) { - return !(lhs < rhs); + return pvoidvector_greater_than_equal(lhs, rhs); + } + + //*************************************************************************** + // Helper functions + //*************************************************************************** + inline bool pvoidvector_equal(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs) + { + return operator ==(lhs, rhs); + } + + inline bool pvoidvector_not_equal(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs) + { + return operator !=(lhs, rhs); + } + + inline bool pvoidvector_less_than(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs) + { + return operator <(lhs, rhs); + } + + inline bool pvoidvector_greater_than(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs) + { + return operator >(lhs, rhs); + } + + inline bool pvoidvector_less_than_equal(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs) + { + return operator <=(lhs, rhs); + } + + inline bool pvoidvector_greater_than_equal(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs) + { + return operator >=(lhs, rhs); } } diff --git a/src/private/map_base.h b/src/private/map_base.h index f23de8da..2ac3256f 100644 --- a/src/private/map_base.h +++ b/src/private/map_base.h @@ -178,8 +178,8 @@ namespace etl /// Constructor //*********************************************************************** Node() : - weight(kNeither), - dir(kNeither) + weight(uint_least8_t(kNeither)), + dir(uint_least8_t(kNeither)) { } @@ -188,13 +188,13 @@ namespace etl //*********************************************************************** void mark_as_leaf() { - weight = kNeither; - dir = kNeither; + weight = uint_least8_t(kNeither); + dir = uint_least8_t(kNeither); children[0] = nullptr; children[1] = nullptr; } - Node* children[2]; + Node* children[2]; uint_least8_t weight; uint_least8_t dir; }; @@ -222,12 +222,12 @@ namespace etl while (weight_node) { // Keep going until we reach a terminal node (dir == kNeither) - if (kNeither != weight_node->dir) + if (uint_least8_t(kNeither) != weight_node->dir) { // Does this insert balance the previous weight factor value? if (weight_node->weight == 1 - weight_node->dir) { - weight_node->weight = kNeither; + weight_node->weight = uint_least8_t(kNeither); } else { @@ -245,14 +245,14 @@ namespace etl } // while(weight_node) // Step 2: Update weight for critical_node or rotate tree to balance node - if (kNeither == critical_node->weight) + if (uint_least8_t(kNeither) == critical_node->weight) { critical_node->weight = critical_node->dir; } // If direction is different than weight, then it will now be balanced else if (critical_node->dir != critical_node->weight) { - critical_node->weight = kNeither; + critical_node->weight = uint_least8_t(kNeither); } // Rotate is required to balance the tree at the critical node else @@ -296,11 +296,11 @@ namespace etl // New root now becomes parent of current position new_root->children[1 - dir] = position; // Clear weight factor from current position - position->weight = kNeither; + position->weight = uint_least8_t(kNeither); // Newly detached right now becomes current position position = new_root; // Clear weight factor from new root - position->weight = kNeither; + position->weight = uint_least8_t(kNeither); } //************************************************************************* @@ -323,7 +323,7 @@ namespace etl // Capture new root (either E or D depending on dir) Node* new_root = position->children[dir]->children[1 - dir]; // Set weight factor for B or C based on F or G existing and being a different than dir - position->children[dir]->weight = third != kNeither && third != dir ? dir : kNeither; + position->children[dir]->weight = third != uint_least8_t(kNeither) && third != dir ? dir : uint_least8_t(kNeither); // Detach new root from its tree (replace with new roots child) position->children[dir]->children[1 - dir] = @@ -331,7 +331,7 @@ namespace etl // Attach current left tree to new root new_root->children[dir] = position->children[dir]; // Set weight factor for A based on F or G - position->weight = third != kNeither && third == dir ? 1 - dir : kNeither; + position->weight = third != uint_least8_t(kNeither) && third == dir ? 1 - dir : uint_least8_t(kNeither); // Move new root's right tree to current roots left tree position->children[dir] = new_root->children[1 - dir]; @@ -340,7 +340,7 @@ namespace etl // Replace current position with new root position = new_root; // Clear weight factor for new current position - position->weight = kNeither; + position->weight = uint_least8_t(kNeither); } //************************************************************************* diff --git a/src/private/pvoidvector.h b/src/private/pvoidvector.h index 165d0c32..010b47c0 100644 --- a/src/private/pvoidvector.h +++ b/src/private/pvoidvector.h @@ -392,7 +392,7 @@ namespace etl //************************************************************************* /// Removes an element from the end of the vector. - /// Undefined behaviour if the vector is empty. + /// Does nothing if the vector is empty. //************************************************************************* void pop_back() { @@ -616,6 +616,20 @@ namespace etl // Disable copy construction. pvoidvector(const pvoidvector&); }; + + bool pvoidvector_equal(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs); + bool pvoidvector_not_equal(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs); + bool pvoidvector_less_than(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs); + bool pvoidvector_greater_than(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs); + bool pvoidvector_less_than_equal(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs); + bool pvoidvector_greater_than_equal(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs); + + bool operator ==(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs); + bool operator !=(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs); + bool operator <(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs); + bool operator >(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs); + bool operator <=(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs); + bool operator >=(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs); } #ifdef ETL_COMPILER_MICROSOFT diff --git a/src/string.h b/src/string.h index 055c1fc9..26f1fbdf 100644 --- a/src/string.h +++ b/src/string.h @@ -182,19 +182,16 @@ namespace etl value_type buffer[MAX_SIZE + 1]; }; - //*************************************************************************** - /// Specialisation for string. - ///\ingroup hash - //*************************************************************************** + //************************************************************************* + /// Hash function. + //************************************************************************* template <> - struct hash + struct hash { - size_t operator ()(const string& s) const + size_t operator()(const etl::istring& text) const { - uint8_t* p_begin = &s[0]; - uint8_t* p_end = &s[s.size()]; - - return etl::__private_hash__::generic_hash(p_begin, p_end); + return etl::__private_hash__::generic_hash<>(reinterpret_cast(&text[0]), + reinterpret_cast(&text[text.size()])); } }; } diff --git a/src/type_def.h b/src/type_def.h index 707a0732..66d6156e 100644 --- a/src/type_def.h +++ b/src/type_def.h @@ -40,11 +40,11 @@ namespace etl /// Usage: ///\code /// // Short form. - /// ETL_TYPEDEF(int, mytype_t); + /// ETL_TYPEDEF(int, mytype); /// /// // Long form. /// class mytype_t_tag; - /// typedef etl::type_def mytype_t; + /// typedef etl::type_def mytype_t_tag; ///\endcode //************************************************************************* template @@ -79,18 +79,6 @@ namespace etl return value; } - //********************************************************************* - explicit operator bool() const - { - return static_cast(value); - } - - //********************************************************************* - bool operator !() const - { - return !bool(value); - } - //********************************************************************* type_def& operator ++() { @@ -255,35 +243,11 @@ namespace etl } //********************************************************************* - const TValue& get() const + TValue get() const { return value; } - //********************************************************************* - friend type_def operator +(const type_def& lhs, const type_def& rhs) - { - return type_def(lhs.value + rhs.value); - } - - //********************************************************************* - friend type_def operator -(const type_def& lhs, const type_def& rhs) - { - return type_def(lhs.value - rhs.value); - } - - //********************************************************************* - friend type_def operator *(const type_def& lhs, const type_def& rhs) - { - return type_def(lhs.value * rhs.value); - } - - //********************************************************************* - friend type_def operator /(const type_def& lhs, const type_def& rhs) - { - return type_def(lhs.value / rhs.value); - } - //********************************************************************* friend bool operator <(const type_def& lhs, const type_def& rhs) { diff --git a/src/type_traits.h b/src/type_traits.h index 605aa63d..776bfda0 100644 --- a/src/type_traits.h +++ b/src/type_traits.h @@ -47,15 +47,15 @@ namespace etl template struct integral_constant { - static const T value = VALUE; + static const T value = VALUE; - typedef T value_type; + typedef T value_type; typedef integral_constant type; - operator value_type() const - { - return value; - } + operator value_type() const + { + return value; + } }; /// integral_constant specialisations @@ -242,19 +242,16 @@ namespace etl template struct make_signed { typedef T type; }; template <> struct make_signed { typedef signed char type; }; template <> struct make_signed { typedef signed char type; }; -#if defined(ETL_COMPILER_GCC) + template <> struct make_signed { - typedef wchar_t type; + typedef typename etl::conditional::type>::type type; }; -#else - template <> struct make_signed - { - typedef etl::conditional::type>::type>::type type; - }; -#endif + template <> struct make_signed { typedef short type; }; template <> struct make_signed { typedef int type; }; template <> struct make_signed { typedef long type; }; @@ -269,19 +266,16 @@ namespace etl template <> struct make_unsigned { typedef unsigned char type; }; template <> struct make_unsigned { typedef unsigned char type; }; template <> struct make_unsigned { typedef unsigned short type; }; -#if defined(ETL_COMPILER_GCC) && !defined(ETL_PLATFORM_LINUX) + template <> struct make_unsigned { - typedef wchar_t type; + typedef typename etl::conditional::type>::type type; }; -#else - template <> struct make_unsigned - { - typedef etl::conditional::type>::type>::type type; - }; -#endif + template <> struct make_unsigned { typedef unsigned int type; }; template <> struct make_unsigned { typedef unsigned long type; }; template <> struct make_unsigned { typedef unsigned long long type; }; diff --git a/src/u16string.h b/src/u16string.h index 138fa916..95766d2b 100644 --- a/src/u16string.h +++ b/src/u16string.h @@ -182,19 +182,16 @@ namespace etl value_type buffer[MAX_SIZE + 1]; }; - //*************************************************************************** - /// Specialisation for u16string. - ///\ingroup hash - //*************************************************************************** + //************************************************************************* + /// Hash function. + //************************************************************************* template <> - struct hash + struct hash { - size_t operator ()(const u16string& s) const + size_t operator()(const etl::iu16string& text) const { - uint8_t* p_begin = &s[0]; - uint8_t* p_end = &s[s.size()]; - - return etl::__private_hash__::generic_hash(p_begin, p_end); + return etl::__private_hash__::generic_hash<>(reinterpret_cast(&text[0]), + reinterpret_cast(&text[text.size()])); } }; } diff --git a/src/u32string.h b/src/u32string.h index 8280fbba..4493acad 100644 --- a/src/u32string.h +++ b/src/u32string.h @@ -182,19 +182,16 @@ namespace etl value_type buffer[MAX_SIZE + 1]; }; - //*************************************************************************** - /// Specialisation for u32string. - ///\ingroup hash - //*************************************************************************** + //************************************************************************* + /// Hash function. + //************************************************************************* template <> - struct hash + struct hash { - size_t operator ()(const u32string& s) const + size_t operator()(const etl::iu32string& text) const { - uint8_t* p_begin = &s[0]; - uint8_t* p_end = &s[s.size()]; - - return etl::__private_hash__::generic_hash(p_begin, p_end); + return etl::__private_hash__::generic_hash<>(reinterpret_cast(&text[0]), + reinterpret_cast(&text[text.size()])); } }; } diff --git a/src/variant.h b/src/variant.h index 613c3c61..767432a8 100644 --- a/src/variant.h +++ b/src/variant.h @@ -225,6 +225,14 @@ namespace etl public: + //*************************************************************************** + /// Destructor. + //*************************************************************************** + ~variant() + { + destruct_current(); + } + //************************************************************************* //**** Reader types ******************************************************* //************************************************************************* @@ -712,17 +720,21 @@ namespace etl ///\param other The other variant object to copy. //*************************************************************************** variant(const variant& other) - : data(other.data), - type_id(other.type_id) { - } + switch (other.type_id) + { + case 0: new(static_cast(data)) T1(other.get()); break; + case 1: new(static_cast(data)) T2(other.get()); break; + case 2: new(static_cast(data)) T3(other.get()); break; + case 3: new(static_cast(data)) T4(other.get()); break; + case 4: new(static_cast(data)) T5(other.get()); break; + case 5: new(static_cast(data)) T6(other.get()); break; + case 6: new(static_cast(data)) T7(other.get()); break; + case 7: new(static_cast(data)) T8(other.get()); break; + default: break; + } - //*************************************************************************** - /// Destructor. - //*************************************************************************** - ~variant() - { - destruct_current(); + type_id = other.type_id; } //*************************************************************************** @@ -734,18 +746,37 @@ namespace etl { STATIC_ASSERT(Type_Is_Supported::value, "Unsupported type"); - // Assigning the same type as last time? - if (type_id == Type_Id_Lookup::type_id) + destruct_current(); + new(static_cast(data)) T(value); + type_id = Type_Id_Lookup::type_id; + + return *this; + } + + //*************************************************************************** + /// Assignment operator for variant type. + ///\param other The variant to assign. + //*************************************************************************** + variant& operator =(const variant& other) + { + if (this != &other) { - // Do a simple copy. - *static_cast(data) = value; - } - else - { - // We must destruct the old type, as the new one is different. destruct_current(); - new(static_cast(data)) T(value); - type_id = Type_Id_Lookup::type_id; + + switch (other.type_id) + { + case 0: new(static_cast(data)) T1(other.get()); break; + case 1: new(static_cast(data)) T2(other.get()); break; + case 2: new(static_cast(data)) T3(other.get()); break; + case 3: new(static_cast(data)) T4(other.get()); break; + case 4: new(static_cast(data)) T5(other.get()); break; + case 5: new(static_cast(data)) T6(other.get()); break; + case 6: new(static_cast(data)) T7(other.get()); break; + case 7: new(static_cast(data)) T8(other.get()); break; + default: break; + } + + type_id = other.type_id; } return *this; @@ -923,6 +954,8 @@ namespace etl case 7: { static_cast(data)->~T8(); break; } default: { break; } } + + type_id = UNSUPPORTED_TYPE_ID; } //*************************************************************************** diff --git a/src/wstring.h b/src/wstring.h index 94bebc6b..6633173c 100644 --- a/src/wstring.h +++ b/src/wstring.h @@ -183,19 +183,16 @@ namespace etl value_type buffer[MAX_SIZE + 1]; }; - //*************************************************************************** - /// Specialisation for wstring. - ///\ingroup hash - //*************************************************************************** + //************************************************************************* + /// Hash function. + //************************************************************************* template <> - struct hash + struct hash { - size_t operator ()(const wstring& s) const + size_t operator()(const etl::iwstring& text) const { - uint8_t* p_begin = &s[0]; - uint8_t* p_end = &s[s.size()]; - - return etl::__private_hash__::generic_hash(p_begin, p_end); + return etl::__private_hash__::generic_hash<>(reinterpret_cast(&text[0]), + reinterpret_cast(&text[text.size()])); } }; } diff --git a/test/test_intrusive_forward_list.cpp b/test/test_intrusive_forward_list.cpp index 089b005c..46ce13b7 100644 --- a/test/test_intrusive_forward_list.cpp +++ b/test/test_intrusive_forward_list.cpp @@ -259,73 +259,58 @@ namespace ////************************************************************************* TEST_FIXTURE(SetupFixture, test_two_lists_different) { - int i = 0; + std::list compare0; + std::list compare1; + + DataNDC0 data0; + DataNDC1 data1; - { - std::list compare0; - std::list compare1; - { - ItemNDCNode node0("0"); - ItemNDCNode node1("1"); - ItemNDCNode node2("2"); - ItemNDCNode node3("3"); - ItemNDCNode node4("4"); - ItemNDCNode node5("5"); - ItemNDCNode node6("6"); - ItemNDCNode node7("7"); + ItemNDCNode node0("0"); + ItemNDCNode node1("1"); + ItemNDCNode node2("2"); + ItemNDCNode node3("3"); + ItemNDCNode node4("4"); + ItemNDCNode node5("5"); + ItemNDCNode node6("6"); + ItemNDCNode node7("7"); - { - DataNDC0 data0; - DataNDC1 data1; + compare0.push_front(node0); + compare0.push_front(node1); + compare0.push_front(node2); + compare0.push_front(node4); + compare0.push_front(node6); + compare0.push_front(node7); + + data0.push_front(node0); + data0.push_front(node1); + data0.push_front(node2); + data0.push_front(node4); + data0.push_front(node6); + data0.push_front(node7); + are_equal = std::equal(data0.begin(), data0.end(), compare0.begin()); + CHECK(are_equal); + CHECK_EQUAL(6, data0.size()); + CHECK_EQUAL(6, std::distance(data0.begin(), data0.end())); + compare1.push_front(node0); + compare1.push_front(node1); + compare1.push_front(node3); + compare1.push_front(node4); + compare1.push_front(node5); + compare1.push_front(node7); - compare0.push_front(node0); - compare0.push_front(node1); - compare0.push_front(node2); - compare0.push_front(node4); - compare0.push_front(node6); - compare0.push_front(node7); + data1.push_front(node0); + data1.push_front(node1); + data1.push_front(node3); + data1.push_front(node4); + data1.push_front(node5); + data1.push_front(node7); - compare1.push_front(node0); - compare1.push_front(node1); - compare1.push_front(node3); - compare1.push_front(node4); - compare1.push_front(node5); - compare1.push_front(node7); - - data0.push_front(node0); - data0.push_front(node1); - data0.push_front(node2); - data0.push_front(node4); - data0.push_front(node6); - data0.push_front(node7); - - data1.push_front(node0); - data1.push_front(node1); - data1.push_front(node3); - data1.push_front(node4); - data1.push_front(node5); - data1.push_front(node7); - - are_equal = std::equal(data0.begin(), data0.end(), compare0.begin()); - CHECK(are_equal); - CHECK_EQUAL(6, data0.size()); - CHECK_EQUAL(6, std::distance(data0.begin(), data0.end())); - - are_equal = std::equal(data1.begin(), data1.end(), compare1.begin()); - CHECK(are_equal); - CHECK_EQUAL(6, data1.size()); - CHECK_EQUAL(6, std::distance(data1.begin(), data1.end())); - } - - size_t temp = compare0.size(); - } - - size_t temp = compare0.size(); - } - - i = 1; + are_equal = std::equal(data1.begin(), data1.end(), compare1.begin()); + CHECK(are_equal); + CHECK_EQUAL(6, data1.size()); + CHECK_EQUAL(6, std::distance(data1.begin(), data1.end())); } //************************************************************************* @@ -346,9 +331,9 @@ namespace std::forward_list::iterator i_compare_data = compare_data.begin(); std::advance(i_compare_data, offset); - compare_data.insert_after(i_compare_data, INSERT_VALUE1); data0.insert_after(i_data, INSERT_VALUE1); - + compare_data.insert_after(i_compare_data, INSERT_VALUE1); + are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin()); CHECK(are_equal); CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data0.size()); @@ -369,16 +354,8 @@ namespace std::forward_list temp(data0.begin(), data0.end()); - compare_data.insert_after(i_compare_data, INSERT_VALUE2); data0.insert_after(i_data, INSERT_VALUE2); - - // Clear the nodes in the temp list. - std::forward_list::iterator itr = temp.begin(); - while (itr != temp.end()) - { - itr->FirstLink::clear(); - ++itr; - } + compare_data.insert_after(i_compare_data, INSERT_VALUE2); temp.assign(data0.begin(), data0.end()); @@ -391,22 +368,6 @@ namespace CHECK(are_equal); CHECK_EQUAL(sorted_data.size(), data1.size()); CHECK_EQUAL(sorted_data.size(), std::distance(data1.begin(), data1.end())); - - // Clear the nodes in the compare list. - itr = compare_data.begin(); - while (itr != compare_data.end()) - { - itr->FirstLink::clear(); - ++itr; - } - - // Clear the nodes in the temp list. - itr = temp.begin(); - while (itr != temp.end()) - { - itr->FirstLink::clear(); - ++itr; - } } //************************************************************************* @@ -430,13 +391,6 @@ namespace CHECK_EQUAL(test1.size(), data1.size()); CHECK_EQUAL(test1.size(), std::distance(data1.begin(), data1.end())); - std::forward_list::iterator itr = compare.begin(); - while (itr != compare.end()) - { - itr->FirstLink::clear(); - ++itr; - } - compare.assign(test1.begin(), test1.end()); data0.assign(test1.begin(), test1.end()); @@ -458,22 +412,6 @@ namespace CHECK(are_equal); CHECK_EQUAL(test1.size(), data1.size()); CHECK_EQUAL(test1.size(), std::distance(data1.begin(), data1.end())); - - // Clear the nodes in the compare list. - itr = compare.begin(); - while (itr != compare.end()) - { - itr->FirstLink::clear(); - ++itr; - } - - // Clear the nodes in the out list. - itr = out.begin(); - while (itr != out.end()) - { - itr->FirstLink::clear(); - ++itr; - } } //************************************************************************* @@ -503,20 +441,10 @@ namespace CHECK_NO_THROW(data0.push_front(node5)); CHECK_NO_THROW(data0.push_front(node6)); - //are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin()); - //CHECK(are_equal); + are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin()); + CHECK(are_equal); CHECK_EQUAL(6, data0.size()); CHECK_EQUAL(6, std::distance(data0.begin(), data0.end())); - - // Clear the nodes in the compare list. - std::list::iterator itr = compare_data.begin(); - while (itr != compare_data.end()) - { - itr->FirstLink::clear(); - ++itr; - } - - data0.clear(); } //************************************************************************* @@ -569,9 +497,6 @@ namespace CHECK_EQUAL(6, data1.size()); CHECK_EQUAL(6, std::distance(data1.begin(), data1.end())); CHECK(!data1.empty()); - - data0.clear(); - data1.clear(); } //************************************************************************* @@ -632,16 +557,6 @@ namespace are_equal = *i_data == *i_compare_data; CHECK(are_equal); - - //std::forward_list::iterator itr = compare_data.begin(); - //while (itr != compare_data.end()) - //{ - // itr->FirstLink::clear(); - // ++itr; - //} - - data0.clear(); - data1.clear(); } //************************************************************************* @@ -678,9 +593,6 @@ namespace CHECK(are_equal); CHECK_EQUAL(sorted_data.size(), data1.size()); CHECK_EQUAL(sorted_data.size(), std::distance(data1.begin(), data1.end())); - - data0.clear(); - data1.clear(); } //************************************************************************* @@ -711,9 +623,6 @@ namespace CHECK(are_equal); CHECK_EQUAL(sorted_data.size(), data1.size()); CHECK_EQUAL(sorted_data.size(), std::distance(data1.begin(), data1.end())); - - data0.clear(); - data1.clear(); } //************************************************************************* @@ -852,25 +761,16 @@ namespace DataNDC0 data0(sorted_data.begin(), sorted_data.end()); DataNDC0 data1(sorted_data2.begin(), sorted_data2.end()); - size_t i0 = data0.size(); - size_t i1 = data0.size(); - DataNDC0::iterator idata_destination = data0.begin(); - std::advance(idata_destination, 1); - - size_t t1 = data0.size(); + std::advance(idata_destination, 3); std::forward_list compare0(data0.begin(), data0.end()); std::forward_list compare1(data1.begin(), data1.end()); std::forward_list::iterator icompare_destination = compare0.begin(); - std::advance(icompare_destination, 1); + std::advance(icompare_destination, 3); data0.splice_after(idata_destination, data1); - - size_t t2 = data0.size(); - size_t t3 = data1.size(); - compare0.splice_after(icompare_destination, compare1); are_equal = std::equal(data0.begin(), data0.end(), compare0.begin()); @@ -878,23 +778,6 @@ namespace CHECK_EQUAL(std::distance(compare0.begin(), compare0.end()), data0.size()); CHECK_EQUAL(std::distance(compare1.begin(), compare1.end()), data1.size()); - - std::forward_list::iterator itr = compare0.begin(); - while (itr != compare0.end()) - { - itr->FirstLink::clear(); - ++itr; - } - - itr = compare1.begin(); - while (itr != compare1.end()) - { - itr->FirstLink::clear(); - ++itr; - } - - data0.clear(); - data1.clear(); } //************************************************************************* @@ -919,15 +802,6 @@ namespace CHECK(are_equal); CHECK_EQUAL(std::distance(compare0.begin(), compare0.end()), data0.size()); - - std::forward_list::iterator itr = compare0.begin(); - while (itr != compare0.end()) - { - itr->FirstLink::clear(); - ++itr; - } - - data0.clear(); } //************************************************************************* @@ -967,23 +841,6 @@ namespace CHECK_EQUAL(std::distance(compare0.begin(), compare0.end()), data0.size()); CHECK_EQUAL(std::distance(compare1.begin(), compare1.end()), data1.size()); - - std::forward_list::iterator itr = compare0.begin(); - while (itr != compare0.end()) - { - itr->FirstLink::clear(); - ++itr; - } - - itr = compare1.begin(); - while (itr != compare1.end()) - { - itr->FirstLink::clear(); - ++itr; - } - - data0.clear(); - data1.clear(); } //************************************************************************* @@ -1020,15 +877,6 @@ namespace CHECK(are_equal); CHECK_EQUAL(std::distance(compare0.begin(), compare0.end()), data0.size()); - - std::forward_list::iterator itr = compare0.begin(); - while (itr != compare0.end()) - { - itr->FirstLink::clear(); - ++itr; - } - - data0.clear(); } //************************************************************************* @@ -1050,23 +898,6 @@ namespace CHECK_EQUAL(std::distance(compare0.begin(), compare0.end()), data0.size()); CHECK_EQUAL(std::distance(compare1.begin(), compare1.end()), data1.size()); - - std::forward_list::iterator itr = compare0.begin(); - while (itr != compare0.end()) - { - itr->FirstLink::clear(); - ++itr; - } - - itr = compare1.begin(); - while (itr != compare1.end()) - { - itr->FirstLink::clear(); - ++itr; - } - - data0.clear(); - data1.clear(); } //************************************************************************* @@ -1088,23 +919,6 @@ namespace CHECK_EQUAL(std::distance(compare0.begin(), compare0.end()), data0.size()); CHECK_EQUAL(std::distance(compare2.begin(), compare2.end()), data2.size()); - - std::forward_list::iterator itr = compare0.begin(); - while (itr != compare0.end()) - { - itr->FirstLink::clear(); - ++itr; - } - - itr = compare2.begin(); - while (itr != compare2.end()) - { - itr->FirstLink::clear(); - ++itr; - } - - data0.clear(); - data2.clear(); } //************************************************************************* @@ -1126,23 +940,6 @@ namespace CHECK_EQUAL(std::distance(compare0.begin(), compare0.end()), data0.size()); CHECK_EQUAL(std::distance(compare3.begin(), compare3.end()), data3.size()); - - std::forward_list::iterator itr = compare0.begin(); - while (itr != compare0.end()) - { - itr->FirstLink::clear(); - ++itr; - } - - itr = compare3.begin(); - while (itr != compare3.end()) - { - itr->FirstLink::clear(); - ++itr; - } - - data0.clear(); - data3.clear(); } //************************************************************************* @@ -1164,23 +961,6 @@ namespace CHECK_EQUAL(std::distance(compare0.begin(), compare0.end()), data0.size()); CHECK_EQUAL(std::distance(compare4.begin(), compare4.end()), data4.size()); - - std::forward_list::iterator itr = compare0.begin(); - while (itr != compare0.end()) - { - itr->FirstLink::clear(); - ++itr; - } - - itr = compare4.begin(); - while (itr != compare4.end()) - { - itr->FirstLink::clear(); - ++itr; - } - - data0.clear(); - data4.clear(); } //************************************************************************* @@ -1208,23 +988,6 @@ namespace CHECK_EQUAL(std::distance(compare0.begin(), compare0.end()), data0.size()); CHECK_EQUAL(std::distance(compare1.begin(), compare1.end()), data1.size()); - - std::forward_list::iterator itr = compare0.begin(); - while (itr != compare0.end()) - { - itr->FirstLink::clear(); - ++itr; - } - - itr = compare1.begin(); - while (itr != compare1.end()) - { - itr->FirstLink::clear(); - ++itr; - } - - data0.clear(); - data1.clear(); } }; } diff --git a/test/test_intrusive_links.cpp b/test/test_intrusive_links.cpp index bb2251cf..9351497b 100644 --- a/test/test_intrusive_links.cpp +++ b/test/test_intrusive_links.cpp @@ -349,7 +349,7 @@ namespace CHECK(data2.SecondFLink::etl_next == &data0); CHECK(data0.SecondFLink::etl_next == nullptr); - // Check checked link. + // Check auto link. etl::link(data0, data1); etl::link(data1, data2); etl::link(data2, data3); @@ -360,11 +360,6 @@ namespace CHECK(data0.ThirdFLinkChecked::etl_next == &data1); CHECK(data1.ThirdFLinkChecked::etl_next == &data3); CHECK(data3.ThirdFLinkChecked::etl_next == nullptr); - - data0.ThirdFLinkChecked::clear(); - data1.ThirdFLinkChecked::clear(); - data2.ThirdFLinkChecked::clear(); - data3.ThirdFLinkChecked::clear(); } //************************************************************************* diff --git a/test/test_variant.cpp b/test/test_variant.cpp index 12967dc7..8583c239 100644 --- a/test/test_variant.cpp +++ b/test/test_variant.cpp @@ -192,6 +192,22 @@ namespace CHECK(variant_2.is_valid()); } + //************************************************************************* + TEST(test_assign_from_variant2) + { + std::string text("Some Text"); + int integer(99); + test_variant_3a variant_1; + test_variant_3a variant_2; + + variant_1 = text; + variant_2 = integer; + variant_2 = variant_1; + + CHECK_EQUAL(text, variant_2.get()); + CHECK(variant_2.is_valid()); + } + //************************************************************************* TEST(test_assignment_incorrect_type_exception) { diff --git a/test/vs2015/etl.vcxproj b/test/vs2015/etl.vcxproj index 87e98819..c671e270 100644 --- a/test/vs2015/etl.vcxproj +++ b/test/vs2015/etl.vcxproj @@ -70,7 +70,7 @@ Level3 Disabled - WIN32;_DEBUG;_CNSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;ETL_THROW_EXCEPTIONS;ETL_VERBOSE_ERRORS;ETL_CHECK_PUSH_POP;ETL_PLATFORM_WINDOWS;%(PreprocessorDefinitions) + WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;ETL_THROW_EXCEPTIONS;ETL_VERBOSE_ERRORS;ETL_CHECK_PUSH_POP;%(PreprocessorDefinitions) ../../../unittest-cpp @@ -185,7 +185,6 @@ - @@ -248,7 +247,6 @@ - @@ -359,9 +357,15 @@ - - - + + true + + + true + + + true + diff --git a/test/vs2015/etl.vcxproj.filters b/test/vs2015/etl.vcxproj.filters index e8fbae31..244fdd50 100644 --- a/test/vs2015/etl.vcxproj.filters +++ b/test/vs2015/etl.vcxproj.filters @@ -522,12 +522,6 @@ ETL\Containers - - ETL\Private - - - ETL\Maths -