Added hash functions

This commit is contained in:
John Wellbelove 2016-12-28 12:40:29 +00:00
parent 8c1f678ac9
commit d58f675722
28 changed files with 353 additions and 535 deletions

View File

@ -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.
//***************************************************************************

View File

@ -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

View File

@ -50,9 +50,9 @@ namespace etl
/// Hash to use when size_t is 16 bits.
/// T is always expected to be size_t.
//*************************************************************************
template <typename T>
template <typename T = size_t>
typename enable_if<sizeof(T) == sizeof(uint16_t), size_t>::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 <typename T>
template <typename T = size_t>
typename enable_if<sizeof(T) == sizeof(uint32_t), size_t>::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 <typename T>
template <typename T = size_t>
typename enable_if<sizeof(T) == sizeof(uint64_t), size_t>::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
{

View File

@ -36,7 +36,7 @@ SOFTWARE.
#include <algorithm>
#include <functional>
#include <stddef.h>
#include <cstring>
#include <string.h>
#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;
}
//*********************************************************************

View File

@ -256,7 +256,7 @@ namespace etl
const Node* p_node;
};
typedef typename std::iterator_traits<iterator>::difference_type difference_type;
typedef typename std::iterator_traits<iterator>::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 <typename TIterator>
@ -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())

View File

@ -325,7 +325,7 @@ namespace etl
const value_type* p_value;
};
typedef typename std::iterator_traits<iterator>::difference_type difference_type;
typedef typename std::iterator_traits<iterator>::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);

View File

@ -149,7 +149,7 @@ namespace etl
struct forward_link<ID_, etl::link_option::AUTO>;
//******************************************************************
// 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;

View File

@ -342,7 +342,7 @@ namespace etl
const value_type* p_value;
};
typedef typename std::iterator_traits<iterator>::difference_type difference_type;
typedef typename std::iterator_traits<iterator>::difference_type difference_type;
//*************************************************************************
/// Constructor.

View File

@ -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();
}
//*************************************************************************

View File

@ -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()
{

View File

@ -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()
{

View File

@ -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()
{

View File

@ -61,4 +61,3 @@ namespace etl
213, 163, 150, 101, 129, 14, 249, 205, 214, 1, 41, 56, 162, 72, 239, 82
} ;
}

View File

@ -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 <typename T>
bool operator ==(const etl::ivector<T*>& lhs, const etl::ivector<T*>& 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 <typename T>
bool operator !=(const etl::ivector<T*>& lhs, const etl::ivector<T*>& rhs)
{
return !(lhs == rhs);
return pvoidvector_not_equal(lhs, rhs);
}
//***************************************************************************
@ -482,7 +482,7 @@ namespace etl
template <typename T>
bool operator <(const etl::ivector<T*>& lhs, const etl::ivector<T*>& 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 <typename T>
bool operator >(const etl::ivector<T*>& lhs, const etl::ivector<T*>& rhs)
{
return (rhs < lhs);
return pvoidvector_greater_than(lhs, rhs);
}
//***************************************************************************
@ -508,7 +508,7 @@ namespace etl
template <typename T>
bool operator <=(const etl::ivector<T*>& lhs, const etl::ivector<T*>& rhs)
{
return !(lhs > rhs);
return pvoidvector_less_than_equal(lhs, rhs);
}
//***************************************************************************
@ -521,7 +521,40 @@ namespace etl
template <typename T>
bool operator >=(const etl::ivector<T*>& lhs, const etl::ivector<T*>& 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);
}
}

View File

@ -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);
}
//*************************************************************************

View File

@ -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

View File

@ -182,19 +182,16 @@ namespace etl
value_type buffer[MAX_SIZE + 1];
};
//***************************************************************************
/// Specialisation for string.
///\ingroup hash
//***************************************************************************
//*************************************************************************
/// Hash function.
//*************************************************************************
template <>
struct hash <string>
struct hash<etl::istring>
{
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<const uint8_t*>(&text[0]),
reinterpret_cast<const uint8_t*>(&text[text.size()]));
}
};
}

View File

@ -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_tag, int> mytype_t;
/// typedef etl::type_def<mytype_t_tag, int> mytype_t_tag;
///\endcode
//*************************************************************************
template <typename TIdType, typename TValue>
@ -79,18 +79,6 @@ namespace etl
return value;
}
//*********************************************************************
explicit operator bool() const
{
return static_cast<bool>(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)
{

View File

@ -47,15 +47,15 @@ namespace etl
template <typename T, const T VALUE>
struct integral_constant
{
static const T value = VALUE;
static const T value = VALUE;
typedef T value_type;
typedef T value_type;
typedef integral_constant<T, VALUE> type;
operator value_type() const
{
return value;
}
operator value_type() const
{
return value;
}
};
/// integral_constant specialisations
@ -242,19 +242,16 @@ namespace etl
template <typename T> struct make_signed { typedef T type; };
template <> struct make_signed<char> { typedef signed char type; };
template <> struct make_signed<unsigned char> { typedef signed char type; };
#if defined(ETL_COMPILER_GCC)
template <> struct make_signed<wchar_t>
{
typedef wchar_t type;
typedef typename etl::conditional<sizeof(wchar_t) == sizeof(int16_t),
int16_t,
etl::conditional<sizeof(wchar_t) == sizeof(int32_t),
int32_t,
void>::type>::type type;
};
#else
template <> struct make_signed<wchar_t>
{
typedef etl::conditional<sizeof(wchar_t) == sizeof(short), short,
etl::conditional<sizeof(wchar_t) == sizeof(int), int,
etl::conditional<sizeof(wchar_t) == sizeof(long), long, void>::type>::type>::type type;
};
#endif
template <> struct make_signed<unsigned short> { typedef short type; };
template <> struct make_signed<unsigned int> { typedef int type; };
template <> struct make_signed<unsigned long> { typedef long type; };
@ -269,19 +266,16 @@ namespace etl
template <> struct make_unsigned<char> { typedef unsigned char type; };
template <> struct make_unsigned<signed char> { typedef unsigned char type; };
template <> struct make_unsigned<short> { typedef unsigned short type; };
#if defined(ETL_COMPILER_GCC) && !defined(ETL_PLATFORM_LINUX)
template <> struct make_unsigned<wchar_t>
{
typedef wchar_t type;
typedef typename etl::conditional<sizeof(wchar_t) == sizeof(uint16_t),
uint16_t,
etl::conditional<sizeof(wchar_t) == sizeof(uint32_t),
uint32_t,
void>::type>::type type;
};
#else
template <> struct make_unsigned<wchar_t>
{
typedef etl::conditional<sizeof(wchar_t) == sizeof(unsigned short), unsigned short,
etl::conditional<sizeof(wchar_t) == sizeof(unsigned int), unsigned int,
etl::conditional<sizeof(wchar_t) == sizeof(unsigned long), unsigned long, void>::type>::type>::type type;
};
#endif
template <> struct make_unsigned<int> { typedef unsigned int type; };
template <> struct make_unsigned<long> { typedef unsigned long type; };
template <> struct make_unsigned<long long> { typedef unsigned long long type; };

View File

@ -182,19 +182,16 @@ namespace etl
value_type buffer[MAX_SIZE + 1];
};
//***************************************************************************
/// Specialisation for u16string.
///\ingroup hash
//***************************************************************************
//*************************************************************************
/// Hash function.
//*************************************************************************
template <>
struct hash <u16string>
struct hash<etl::iu16string>
{
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<const uint8_t*>(&text[0]),
reinterpret_cast<const uint8_t*>(&text[text.size()]));
}
};
}

View File

@ -182,19 +182,16 @@ namespace etl
value_type buffer[MAX_SIZE + 1];
};
//***************************************************************************
/// Specialisation for u32string.
///\ingroup hash
//***************************************************************************
//*************************************************************************
/// Hash function.
//*************************************************************************
template <>
struct hash <u32string>
struct hash<etl::iu32string>
{
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<const uint8_t*>(&text[0]),
reinterpret_cast<const uint8_t*>(&text[text.size()]));
}
};
}

View File

@ -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<T1*>(data)) T1(other.get<T1>()); break;
case 1: new(static_cast<T2*>(data)) T2(other.get<T2>()); break;
case 2: new(static_cast<T3*>(data)) T3(other.get<T3>()); break;
case 3: new(static_cast<T4*>(data)) T4(other.get<T4>()); break;
case 4: new(static_cast<T5*>(data)) T5(other.get<T5>()); break;
case 5: new(static_cast<T6*>(data)) T6(other.get<T6>()); break;
case 6: new(static_cast<T7*>(data)) T7(other.get<T7>()); break;
case 7: new(static_cast<T8*>(data)) T8(other.get<T8>()); break;
default: break;
}
//***************************************************************************
/// Destructor.
//***************************************************************************
~variant()
{
destruct_current();
type_id = other.type_id;
}
//***************************************************************************
@ -734,18 +746,37 @@ namespace etl
{
STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
// Assigning the same type as last time?
if (type_id == Type_Id_Lookup<T>::type_id)
destruct_current();
new(static_cast<T*>(data)) T(value);
type_id = Type_Id_Lookup<T>::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<T*>(data) = value;
}
else
{
// We must destruct the old type, as the new one is different.
destruct_current();
new(static_cast<T*>(data)) T(value);
type_id = Type_Id_Lookup<T>::type_id;
switch (other.type_id)
{
case 0: new(static_cast<T1*>(data)) T1(other.get<T1>()); break;
case 1: new(static_cast<T2*>(data)) T2(other.get<T2>()); break;
case 2: new(static_cast<T3*>(data)) T3(other.get<T3>()); break;
case 3: new(static_cast<T4*>(data)) T4(other.get<T4>()); break;
case 4: new(static_cast<T5*>(data)) T5(other.get<T5>()); break;
case 5: new(static_cast<T6*>(data)) T6(other.get<T6>()); break;
case 6: new(static_cast<T7*>(data)) T7(other.get<T7>()); break;
case 7: new(static_cast<T8*>(data)) T8(other.get<T8>()); break;
default: break;
}
type_id = other.type_id;
}
return *this;
@ -923,6 +954,8 @@ namespace etl
case 7: { static_cast<T8*>(data)->~T8(); break; }
default: { break; }
}
type_id = UNSUPPORTED_TYPE_ID;
}
//***************************************************************************

View File

@ -183,19 +183,16 @@ namespace etl
value_type buffer[MAX_SIZE + 1];
};
//***************************************************************************
/// Specialisation for wstring.
///\ingroup hash
//***************************************************************************
//*************************************************************************
/// Hash function.
//*************************************************************************
template <>
struct hash <wstring>
struct hash<etl::iwstring>
{
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<const uint8_t*>(&text[0]),
reinterpret_cast<const uint8_t*>(&text[text.size()]));
}
};
}

View File

@ -259,73 +259,58 @@ namespace
////*************************************************************************
TEST_FIXTURE(SetupFixture, test_two_lists_different)
{
int i = 0;
std::list<ItemNDCNode> compare0;
std::list<ItemNDCNode> compare1;
DataNDC0 data0;
DataNDC1 data1;
{
std::list<ItemNDCNode> compare0;
std::list<ItemNDCNode> 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<ItemNDCNode>::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<ItemNDCNode> 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<ItemNDCNode>::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<ItemNDCNode>::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<ItemNDCNode>::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<ItemNDCNode>::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<ItemNDCNode> compare0(data0.begin(), data0.end());
std::forward_list<ItemNDCNode> compare1(data1.begin(), data1.end());
std::forward_list<ItemNDCNode>::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<ItemNDCNode>::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<ItemNDCNode>::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<ItemNDCNode>::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<ItemNDCNode>::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<ItemNDCNode>::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<ItemNDCNode>::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<ItemNDCNode>::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<ItemNDCNode>::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<ItemNDCNode>::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();
}
};
}

View File

@ -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<ThirdFLinkChecked>(data0, data1);
etl::link<ThirdFLinkChecked>(data1, data2);
etl::link<ThirdFLinkChecked>(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();
}
//*************************************************************************

View File

@ -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<std::string>());
CHECK(variant_2.is_valid());
}
//*************************************************************************
TEST(test_assignment_incorrect_type_exception)
{

View File

@ -70,7 +70,7 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>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)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;ETL_THROW_EXCEPTIONS;ETL_VERBOSE_ERRORS;ETL_CHECK_PUSH_POP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../../../unittest-cpp</AdditionalIncludeDirectories>
<UndefinePreprocessorDefinitions>
</UndefinePreprocessorDefinitions>
@ -185,7 +185,6 @@
<ClInclude Include="..\..\src\flat_set.h" />
<ClInclude Include="..\..\src\fnv_1.h" />
<ClInclude Include="..\..\src\forward_list.h" />
<ClInclude Include="..\..\src\frame_check_sequence.h" />
<ClInclude Include="..\..\src\function.h" />
<ClInclude Include="..\..\src\functional.h" />
<ClInclude Include="..\..\src\hash.h" />
@ -248,7 +247,6 @@
<ClInclude Include="..\..\src\pool.h" />
<ClInclude Include="..\..\src\power.h" />
<ClInclude Include="..\..\src\priority_queue.h" />
<ClInclude Include="..\..\src\private\counter_type.h" />
<ClInclude Include="..\..\src\private\deque_base.h" />
<ClInclude Include="..\..\src\private\flat_map_base.h" />
<ClInclude Include="..\..\src\private\flat_multimap_base.h" />
@ -359,9 +357,15 @@
<ClCompile Include="..\test_hash.cpp" />
<ClCompile Include="..\test_instance_count.cpp" />
<ClCompile Include="..\test_integral_limits.cpp" />
<ClCompile Include="..\test_intrusive_forward_list.cpp" />
<ClCompile Include="..\test_intrusive_links.cpp" />
<ClCompile Include="..\test_intrusive_list.cpp" />
<ClCompile Include="..\test_intrusive_forward_list.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\test_intrusive_links.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\test_intrusive_list.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\test_intrusive_stack.cpp" />
<ClCompile Include="..\test_io_port.cpp" />
<ClCompile Include="..\test_jenkins.cpp" />

View File

@ -522,12 +522,6 @@
<ClInclude Include="..\..\src\intrusive_stack.h">
<Filter>ETL\Containers</Filter>
</ClInclude>
<ClInclude Include="..\..\src\private\counter_type.h">
<Filter>ETL\Private</Filter>
</ClInclude>
<ClInclude Include="..\..\src\frame_check_sequence.h">
<Filter>ETL\Maths</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\unittest-cpp\UnitTest++\AssertException.cpp">