Merge branch 'development'

This commit is contained in:
John Wellbelove 2015-09-28 18:57:15 +01:00
commit 8d8a80212e
66 changed files with 299512 additions and 1252 deletions

16
array.h
View File

@ -39,10 +39,7 @@ SOFTWARE.
#include "type_traits.h"
#include "parameter_type.h"
#include "static_assert.h"
#ifndef ETL_THROW_EXCEPTIONS
#include "error_handler.h"
#endif
///\defgroup array array
/// A replacement for std::array if you haven't got C++0x11.
@ -82,7 +79,7 @@ namespace etl
///\ingroup array
/// A replacement for std::array if you haven't got C++0x11.
//***************************************************************************
template <typename T, const size_t SIZE>
template <typename T, const size_t SIZE_>
class array
{
private:
@ -91,6 +88,11 @@ namespace etl
public:
enum
{
SIZE = SIZE_
};
typedef T value_type;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
@ -138,11 +140,7 @@ namespace etl
{
if (i >= SIZE)
{
#ifdef ETL_THROW_EXCEPTIONS
throw array_out_of_range();
#else
error_handler::error(array_out_of_range());
#endif
ETL_ERROR(array_out_of_range());
}
return _buffer[i];

View File

@ -37,9 +37,56 @@ SOFTWARE.
#include "type_traits.h"
#include "integral_limits.h"
#include "static_assert.h"
#include "log.h"
#include "power.h"
#include "smallest.h"
namespace etl
{
//***************************************************************************
/// Maximum value that can be contained in N bits.
//***************************************************************************
namespace __private_binary__
{
/// Helper definition for non-zero NBITS.
template <const size_t NBITS>
struct max_value_for_nbits_helper
{
typedef typename etl::smallest_uint_for_bits<NBITS>::type value_type;
static const value_type value = (uint64_t(1) << (NBITS - 1)) | max_value_for_nbits_helper<NBITS - 1>::value;
};
/// Specialisation for when NBITS == 0.
template <>
struct max_value_for_nbits_helper<0>
{
typedef etl::smallest_uint_for_bits<0>::type value_type;
static const value_type value = 1;
};
template <const size_t NBITS>
const typename max_value_for_nbits_helper<NBITS>::value_type max_value_for_nbits_helper<NBITS>::value;
}
/// Definition for non-zero NBITS.
template <const size_t NBITS>
struct max_value_for_nbits
{
typedef typename etl::smallest_uint_for_bits<NBITS>::type value_type;
static const value_type value = __private_binary__::max_value_for_nbits_helper<NBITS>::value;
};
/// Specialisation for when NBITS == 0.
template <>
struct max_value_for_nbits<0>
{
typedef etl::smallest_uint_for_bits<0>::type value_type;
static const value_type value = 0;
};
template <const size_t NBITS>
const typename max_value_for_nbits<NBITS>::value_type max_value_for_nbits<NBITS>::value;
//***************************************************************************
/// Rotate left.
//***************************************************************************
@ -421,6 +468,33 @@ namespace etl
return (0x69966996 >> value) & 1;
}
//***************************************************************************
/// Fold a binary number down to a set number of bits using XOR.
//***************************************************************************
template <typename TReturn, const size_t NBITS, typename TValue>
TReturn fold_bits(TValue value)
{
STATIC_ASSERT(integral_limits<TReturn>::bits >= NBITS, "Return type too small to hold result");
const TValue mask = etl::power<2, NBITS>::value - 1;
const size_t shift = NBITS;
// Fold the value down to fit the width.
TReturn folded_value = 0;
// Keep shifting down and XORing the lower bits.
while (value >= etl::max_value_for_nbits<NBITS>::value)
{
folded_value ^= value & mask;
value >>= shift;
}
// Fold the remaining bits.
folded_value ^= value;
return folded_value;
}
//***************************************************************************
/// 8 bit binary constants.
//***************************************************************************

View File

@ -33,6 +33,7 @@ SOFTWARE.
#include "parameter_type.h"
#include "bitset.h"
#include "type_traits.h"
#include "binary.h"
#include "log.h"
#include "power.h"
@ -172,26 +173,10 @@ namespace etl
template <typename THash>
size_t get_hash(parameter_t key) const
{
const size_t mask = etl::power_of_2_round_up<WIDTH>::value - 1;
size_t hash = THash()(key);
// Fold the hash down to fit the width.
size_t folded_hash = 0;
const size_t shift = etl::log2<etl::power_of_2_round_up<WIDTH>::value>::value;
// Keep shifting down and XORing the lower bits.
while (hash >= WIDTH)
{
folded_hash ^= hash & mask;
hash >>= shift;
}
// Fold the remaining bits.
folded_hash ^= hash;
return folded_hash;
return fold_bits<size_t, etl::log2<WIDTH>::value>(hash);
}
/// The Bloom filter flags.

138
bsd_checksum.h Normal file
View File

@ -0,0 +1,138 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
Copyright(c) 2014 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef __ETL_BSDCHECKSUM__
#define __ETL_BSDCHECKSUM__
#include <stdint.h>
#include "static_assert.h"
#include "type_traits.h"
#include "binary.h"
#include "ihash.h"
///\defgroup bsdchecksum BSD Checksum calculation
///\ingroup maths
namespace etl
{
//***************************************************************************
/// Calculates the checksum.
///\tparam TSum The type used for the sum.
///\ingroup checksum
//***************************************************************************
template <typename TSum>
class bsd_checksum
{
public:
STATIC_ASSERT(is_unsigned<TSum>::value, "Signed TSum template parameter not supported");
typedef TSum value_type;
//*************************************************************************
/// Default constructor.
//*************************************************************************
bsd_checksum()
{
reset();
}
//*************************************************************************
/// Constructor from range.
/// \param begin Start of the range.
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
bsd_checksum(TIterator begin, const TIterator end)
{
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Only 8 bit types supported");
reset();
while (begin != end)
{
sum = rotate_right(sum) + *begin++;
}
}
//*************************************************************************
/// Resets the CRC to the initial state.
//*************************************************************************
void reset()
{
sum = 0;
}
//*************************************************************************
/// Adds a range.
/// \param begin
/// \param end
//*************************************************************************
template<typename TIterator>
void add(TIterator begin, const TIterator end)
{
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Only 8 bit types supported");
while (begin != end)
{
sum = rotate_right(sum) + *begin++;
}
}
//*************************************************************************
/// \param value The uint8_t to add to the checksum.
//*************************************************************************
void add(uint8_t value)
{
sum = rotate_right(sum) + value;
}
//*************************************************************************
/// Gets the checksum value.
//*************************************************************************
value_type value()
{
return sum;
}
//*************************************************************************
/// Conversion operator to value_type.
//*************************************************************************
operator value_type ()
{
return sum;
}
private:
value_type sum;
};
}
#endif

View File

@ -34,7 +34,6 @@ SOFTWARE.
#include "static_assert.h"
#include "type_traits.h"
#include "endian.h"
#include "ihash.h"
///\defgroup checksum Checksum calculation
@ -45,11 +44,10 @@ namespace etl
//***************************************************************************
/// Calculates the checksum.
///\tparam TSum The type used for the sum.
///\tparam ENDIANNESS The endianness of the calculation for input types larger than uint8_t. Default = endian::little.
///\ingroup checksum
//***************************************************************************
template <typename TSum, const int ENDIANNESS = endian::little>
class checksum : public etl::ihash
template <typename TSum>
class checksum
{
public:
@ -61,7 +59,6 @@ namespace etl
/// Default constructor.
//*************************************************************************
checksum()
: ihash(etl::endian(ENDIANNESS))
{
reset();
}
@ -73,10 +70,14 @@ namespace etl
//*************************************************************************
template<typename TIterator>
checksum(TIterator begin, const TIterator end)
: ihash(etl::endian(ENDIANNESS))
{
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
reset();
add(begin, end);
while (begin != end)
{
sum += *begin++;
}
}
//*************************************************************************
@ -95,17 +96,12 @@ namespace etl
template<typename TIterator>
void add(TIterator begin, const TIterator end)
{
ihash::add(begin, end);
}
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
//*************************************************************************
/// Adds a value.
/// \param value The value to add to the checksum.
//*************************************************************************
template<typename TValue>
void add(TValue value)
{
ihash::add(value);
while (begin != end)
{
sum += *begin++;
}
}
//*************************************************************************
@ -132,14 +128,6 @@ namespace etl
return sum;
}
//*************************************************************************
/// Gets the generic digest value.
//*************************************************************************
generic_digest digest() const
{
return ihash::get_digest(sum);
}
private:
value_type sum;

38
crc16.h
View File

@ -34,8 +34,6 @@ SOFTWARE.
#include "static_assert.h"
#include "type_traits.h"
#include "endian.h"
#include "ihash.h"
#if defined(COMPILER_KEIL)
#pragma diag_suppress 1300
@ -54,11 +52,9 @@ namespace etl
//***************************************************************************
/// Calculates CRC16 using polynomial 0x8005.
///\tparam ENDIANNESS The endianness of the calculation for input types larger than uint8_t. Default = endian::little.
/// \ingroup crc16
//***************************************************************************
template <const int ENDIANNESS = endian::little>
class crc16 : public etl::ihash
class crc16
{
public:
@ -69,7 +65,6 @@ namespace etl
/// Default constructor.
//*************************************************************************
crc16()
: ihash(etl::endian(ENDIANNESS))
{
reset();
}
@ -81,10 +76,14 @@ namespace etl
//*************************************************************************
template<typename TIterator>
crc16(TIterator begin, const TIterator end)
: ihash(etl::endian(ENDIANNESS))
{
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
reset();
add(begin, end);
while (begin != end)
{
crc = (crc >> 8) ^ CRC16[(crc ^ *begin++) & 0xFF];
}
}
//*************************************************************************
@ -103,17 +102,12 @@ namespace etl
template<typename TIterator>
void add(TIterator begin, const TIterator end)
{
ihash::add(begin, end);
}
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
//*************************************************************************
/// Adds a value.
/// \param value The value to add to the checksum.
//*************************************************************************
template<typename TValue>
void add(TValue value)
{
ihash::add(value);
while (begin != end)
{
crc = (crc >> 8) ^ CRC16[(crc ^ *begin++) & 0xFF];
}
}
//*************************************************************************
@ -141,14 +135,6 @@ namespace etl
return crc;
}
//*************************************************************************
/// Gets the generic digest value.
//*************************************************************************
generic_digest digest() const
{
return ihash::get_digest(crc);
}
private:
value_type crc;

View File

@ -34,8 +34,6 @@ SOFTWARE.
#include "static_assert.h"
#include "type_traits.h"
#include "endian.h"
#include "ihash.h"
#if defined(COMPILER_KEIL)
#pragma diag_suppress 1300
@ -54,11 +52,9 @@ namespace etl
//***************************************************************************
/// Calculates CRC-CCITT using polynomial 0x1021
///\tparam ENDIANNESS The endianness of the calculation for input types larger than uint8_t. Default = endian::little.
/// \ingroup crc16_ccitt
//***************************************************************************
template <const int ENDIANNESS = endian::little>
class crc16_ccitt : public etl::ihash
class crc16_ccitt
{
public:
@ -69,7 +65,6 @@ namespace etl
/// Default constructor.
//*************************************************************************
crc16_ccitt()
: ihash(etl::endian(ENDIANNESS))
{
reset();
}
@ -81,10 +76,14 @@ namespace etl
//*************************************************************************
template<typename TIterator>
crc16_ccitt(TIterator begin, const TIterator end)
: ihash(etl::endian(ENDIANNESS))
{
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
reset();
add(begin, end);
while (begin != end)
{
crc = (crc << 8) ^ CRC_CCITT[((crc >> 8) ^ *begin++) & 0xFF];
}
}
//*************************************************************************
@ -103,17 +102,12 @@ namespace etl
template<typename TIterator>
void add(TIterator begin, const TIterator end)
{
ihash::add(begin, end);
}
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
//*************************************************************************
/// Adds a value.
/// \param value The value to add to the checksum.
//*************************************************************************
template<typename TValue>
void add(TValue value)
{
ihash::add(value);
while (begin != end)
{
crc = (crc << 8) ^ CRC_CCITT[((crc >> 8) ^ *begin++) & 0xFF];
}
}
//*************************************************************************
@ -140,14 +134,6 @@ namespace etl
return crc;
}
//*************************************************************************
/// Gets the generic digest value.
//*************************************************************************
generic_digest digest() const
{
return ihash::get_digest(crc);
}
private:
value_type crc;

View File

@ -34,8 +34,6 @@ SOFTWARE.
#include "static_assert.h"
#include "type_traits.h"
#include "endian.h"
#include "ihash.h"
#if defined(COMPILER_KEIL)
#pragma diag_suppress 1300
@ -54,11 +52,9 @@ namespace etl
//***************************************************************************
/// Calculates CRC-Kermit using polynomial 0x1021
///\tparam ENDIANNESS The endianness of the calculation for input types larger than uint8_t. Default = endian::little.
/// \ingroup crc16_kermit
//***************************************************************************
template <const int ENDIANNESS = endian::little>
class crc16_kermit : public etl::ihash
class crc16_kermit
{
public:
@ -69,7 +65,6 @@ namespace etl
/// Default constructor.
//*************************************************************************
crc16_kermit()
: ihash(etl::endian(ENDIANNESS))
{
reset();
}
@ -81,10 +76,14 @@ namespace etl
//*************************************************************************
template<typename TIterator>
crc16_kermit(TIterator begin, const TIterator end)
: ihash(etl::endian(ENDIANNESS))
{
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
reset();
add(begin, end);
while (begin != end)
{
crc = (crc >> 8) ^ CRC_KERMIT[(crc ^ *begin++) & 0xFF];
}
}
//*************************************************************************
@ -103,17 +102,12 @@ namespace etl
template<typename TIterator>
void add(TIterator begin, const TIterator end)
{
ihash::add(begin, end);
}
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
//*************************************************************************
/// Adds a value.
/// \param value The value to add to the checksum.
//*************************************************************************
template<typename TValue>
void add(TValue value)
{
ihash::add(value);
while (begin != end)
{
crc = (crc >> 8) ^ CRC_KERMIT[(crc ^ *begin++) & 0xFF];
}
}
//*************************************************************************
@ -140,14 +134,6 @@ namespace etl
return crc;
}
//*************************************************************************
/// Gets the generic digest value.
//*************************************************************************
generic_digest digest() const
{
return ihash::get_digest(crc);
}
private:
value_type crc;

39
crc32.h
View File

@ -31,11 +31,9 @@ SOFTWARE.
#define __ETL_CRC32__
#include <stdint.h>
#include <iterator>
#include "static_assert.h"
#include "type_traits.h"
#include "endian.h"
#include "ihash.h"
#if defined(COMPILER_KEIL)
#pragma diag_suppress 1300
@ -54,11 +52,9 @@ namespace etl
//***************************************************************************
/// Calculates CRC32 using polynomial 0x04C11DB7.
///\tparam ENDIANNESS The endianness of the calculation for input types larger than uint8_t. Default = endian::little.
/// \ingroup crc32
//***************************************************************************
template <const int ENDIANNESS = endian::little>
class crc32 : public etl::ihash
class crc32
{
public:
@ -69,7 +65,6 @@ namespace etl
/// Default constructor.
//*************************************************************************
crc32()
: ihash(etl::endian(ENDIANNESS))
{
reset();
}
@ -81,10 +76,13 @@ namespace etl
//*************************************************************************
template<typename TIterator>
crc32(TIterator begin, const TIterator end)
: ihash(etl::endian(ENDIANNESS))
{
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
reset();
add(begin, end);
while (begin != end)
{
crc = (crc >> 8) ^ CRC32[(crc ^ *begin++) & 0xFF];
}
}
//*************************************************************************
@ -103,17 +101,12 @@ namespace etl
template<typename TIterator>
void add(TIterator begin, const TIterator end)
{
ihash::add(begin, end);
}
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
//*************************************************************************
/// Adds a value.
/// \param value The value to add to the checksum.
//*************************************************************************
template<typename TValue>
void add(TValue value)
{
ihash::add(value);
while (begin != end)
{
crc = (crc >> 8) ^ CRC32[(crc ^ *begin++) & 0xFF];
}
}
//*************************************************************************
@ -140,14 +133,6 @@ namespace etl
return crc ^ 0xFFFFFFFF;
}
//*************************************************************************
/// Gets the generic digest value.
//*************************************************************************
generic_digest digest() const
{
return ihash::get_digest(crc);
}
private:
value_type crc;

View File

@ -34,8 +34,6 @@ SOFTWARE.
#include "static_assert.h"
#include "type_traits.h"
#include "endian.h"
#include "ihash.h"
#if defined(COMPILER_KEIL)
#pragma diag_suppress 1300
@ -54,11 +52,9 @@ namespace etl
//***************************************************************************
/// Calculates CRC64-ECMA using polynomial 0x42F0E1EBA9EA3693.
///\tparam ENDIANNESS The endianness of the calculation for input types larger than uint8_t. Default = endian::little.
/// \ingroup crc64_ecma
//***************************************************************************
template <const int ENDIANNESS = endian::little>
class crc64_ecma : public etl::ihash
class crc64_ecma
{
public:
@ -69,7 +65,6 @@ namespace etl
/// Default constructor.
//*************************************************************************
crc64_ecma()
: ihash(etl::endian(ENDIANNESS))
{
reset();
}
@ -81,10 +76,14 @@ namespace etl
//*************************************************************************
template<typename TIterator>
crc64_ecma(TIterator begin, const TIterator end)
: ihash(etl::endian(ENDIANNESS))
{
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
reset();
add(begin, end);
while (begin != end)
{
crc = (crc << 8) ^ CRC64_ECMA[((crc >> 56) ^ *begin++) & 0xFF];
}
}
//*************************************************************************
@ -103,17 +102,12 @@ namespace etl
template<typename TIterator>
void add(TIterator begin, const TIterator end)
{
ihash::add(begin, end);
}
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
//*************************************************************************
/// Adds a value.
/// \param value The value to add to the checksum.
//*************************************************************************
template<typename TValue>
void add(TValue value)
{
ihash::add(value);
while (begin != end)
{
crc = (crc << 8) ^ CRC64_ECMA[((crc >> 56) ^ *begin++) & 0xFF];
}
}
//*************************************************************************
@ -140,14 +134,6 @@ namespace etl
return crc;
}
//*************************************************************************
/// Gets the generic digest value.
//*************************************************************************
generic_digest digest() const
{
return ihash::get_digest(crc);
}
private:
value_type crc;

View File

@ -34,8 +34,6 @@ SOFTWARE.
#include "static_assert.h"
#include "type_traits.h"
#include "endian.h"
#include "ihash.h"
#if defined(COMPILER_KEIL)
#pragma diag_suppress 1300
@ -54,11 +52,9 @@ namespace etl
//***************************************************************************
/// Calculates CRC8 CCITT using polynomial 0x07.
///\tparam ENDIANNESS The endianness of the calculation for input types larger than uint8_t. Default = endian::little.
/// \ingroup crc8_ccitt
//***************************************************************************
template <const int ENDIANNESS = endian::little>
class crc8_ccitt : public etl::ihash
class crc8_ccitt
{
public:
@ -69,7 +65,6 @@ namespace etl
/// Default constructor.
//*************************************************************************
crc8_ccitt()
: ihash(etl::endian(ENDIANNESS))
{
reset();
}
@ -81,10 +76,13 @@ namespace etl
//*************************************************************************
template<typename TIterator>
crc8_ccitt(TIterator begin, const TIterator end)
: ihash(etl::endian(ENDIANNESS))
{
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
reset();
add(begin, end);
while (begin != end)
{
crc = CRC8_CCITT[crc ^ *begin++];
}
}
//*************************************************************************
@ -103,17 +101,11 @@ namespace etl
template<typename TIterator>
void add(TIterator begin, const TIterator end)
{
ihash::add(begin, end);
}
//*************************************************************************
/// Adds a value.
/// \param value The value to add to the checksum.
//*************************************************************************
template<typename TValue>
void add(TValue value)
{
ihash::add(value);
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
while (begin != end)
{
crc = CRC8_CCITT[crc ^ *begin++];
}
}
//*************************************************************************
@ -140,14 +132,6 @@ namespace etl
return crc;
}
//*************************************************************************
/// Gets the generic digest value.
//*************************************************************************
generic_digest digest() const
{
return ihash::get_digest(crc);
}
private:
value_type crc;

View File

@ -50,7 +50,7 @@ namespace etl
{
//***************************************************************************
/// A fixed capacity double ended queue.
///\node The deque allocates one more element than the specified maximum size.
///\note The deque allocates one more element than the specified maximum size.
///\tparam T The type of items this deque holds.
///\tparam MAX_SIZE_ The capacity of the deque
///\ingroup deque

View File

@ -49,12 +49,14 @@ namespace etl
enum enum_type
{
little,
big
big,
native
};
DECLARE_ENUM_TYPE(endian, int)
ENUM_TYPE(little, "little")
ENUM_TYPE(big, "big")
ENUM_TYPE(native, "native")
END_ENUM_TYPE
};

View File

@ -85,14 +85,11 @@ namespace etl
/// the error handler is called.
///\ingroup error_handler
//***************************************************************************
inline void raise_error(const exception& e)
{
#ifdef ETL_THROW_EXCEPTIONS
throw e;
#define ETL_ERROR(e) throw e
#else
error_handler::error(e);
#define ETL_ERROR(e) etl::error_handler::error(e);
#endif
}
}
#endif

View File

@ -32,90 +32,125 @@ SOFTWARE.
#include <iterator>
///\defgroup iterator Iterator types
namespace etl
{
/// A fixed iterator class.
/// This iterator can be given an iterator value, which will not be allowed to be incremented or decremented.
/// This can be useful when using STL algorithms to interact with fixed memory locations such as registers.
///\ingroup iterator
template <typename TIterator>
class fixed_iterator : public std::iterator<std::random_access_iterator_tag, TIterator>
class fixed_iterator : std::iterator<typename std::iterator_traits<TIterator>::iterator_category, typename std::iterator_traits<TIterator>::value_type>
{
public:
//***************************************************************************
/// Default constructor.
//***************************************************************************
fixed_iterator()
: it(TIterator())
{}
{
}
//***************************************************************************
/// Construct from iterator.
//***************************************************************************
fixed_iterator(TIterator it)
: it(it)
{
}
//***************************************************************************
/// Increment (Does nothing).
//***************************************************************************
fixed_iterator& operator ++()
{
return *this;
}
//***************************************************************************
/// Increment (Does nothing).
//***************************************************************************
fixed_iterator operator ++(int)
{
return *this;
}
//***************************************************************************
/// Decrement (Does nothing).
//***************************************************************************
fixed_iterator& operator --()
{
return *this;
}
//***************************************************************************
/// Decrement (Does nothing).
//***************************************************************************
fixed_iterator operator --(int)
{
return *this;
}
//***************************************************************************
/// Dereference operator.
//***************************************************************************
typename std::iterator_traits<TIterator>::value_type operator *()
{
return *it;
}
//***************************************************************************
/// Dereference operator.
//***************************************************************************
const typename std::iterator_traits<TIterator>::value_type operator *() const
{
return *it;
}
//***************************************************************************
/// -> operator.
//***************************************************************************
TIterator operator ->()
{
return it;
}
//***************************************************************************
/// -> operator.
//***************************************************************************
const TIterator operator ->() const
{
return it;
}
//***************************************************************************
/// Conversion operator.
//***************************************************************************
operator TIterator() const
{
return it;
}
//***************************************************************************
/// += operator.
//***************************************************************************
fixed_iterator& operator +=(typename std::iterator_traits<TIterator>::difference_type offset)
{
return *this;
}
//***************************************************************************
/// -= operator.
//***************************************************************************
fixed_iterator& operator -=(typename std::iterator_traits<TIterator>::difference_type offset)
{
return *this;
}
//***************************************************************************
/// Assignment from iterator.
//***************************************************************************
fixed_iterator& operator =(TIterator new_it)
{
@ -124,23 +159,22 @@ namespace etl
}
//***************************************************************************
void set(TIterator new_it)
{
it = new_it;
}
/// Assignment from fixed_iterator.
//***************************************************************************
const TIterator& get() const
fixed_iterator& operator =(fixed_iterator other)
{
return it;
it = other.it;
return *this;
}
private:
TIterator it; ///< The underlying iterator.
};
//*****************************************************************************
//***************************************************************************
/// Makes a fixed_iterator from an iterator.
//***************************************************************************
template <typename TIterator>
fixed_iterator<TIterator> make_fixed_iterator(TIterator it)
{
@ -148,6 +182,8 @@ namespace etl
}
}
//*****************************************************************************
/// + difference operator.
//*****************************************************************************
template <typename TIterator>
etl::fixed_iterator<TIterator>& operator +(etl::fixed_iterator<TIterator>& lhs,
@ -156,6 +192,8 @@ etl::fixed_iterator<TIterator>& operator +(etl::fixed_iterator<TIterator>& lhs,
return lhs;
}
//*****************************************************************************
/// - difference operator.
//*****************************************************************************
template <typename TIterator>
etl::fixed_iterator<TIterator>& operator -(etl::fixed_iterator<TIterator>& lhs,
@ -164,39 +202,49 @@ etl::fixed_iterator<TIterator>& operator -(etl::fixed_iterator<TIterator>& lhs,
return lhs;
}
//*****************************************************************************
/// - fixed_iterator operator.
//*****************************************************************************
template <typename TIterator>
typename std::iterator_traits<TIterator>::difference_type operator -(etl::fixed_iterator<TIterator>& lhs,
etl::fixed_iterator<TIterator>& rhs)
{
return lhs.get() - rhs.get();
return TIterator(lhs) - TIterator(rhs);
}
//*****************************************************************************
/// Equality operator. fixed_iterator == fixed_iterator.
//*****************************************************************************
template <typename TIterator>
bool operator ==(const etl::fixed_iterator<TIterator>& lhs,
const etl::fixed_iterator<TIterator>& rhs)
{
return lhs.get() == rhs.get();
return TIterator(lhs) == TIterator(rhs);
}
//*****************************************************************************
/// Equality operator. fixed_iterator == iterator.
//*****************************************************************************
template <typename TIterator>
bool operator ==(const etl::fixed_iterator<TIterator>& lhs,
TIterator rhs)
{
return lhs.get() == rhs;
return TIterator(lhs) == rhs;
}
//*****************************************************************************
/// Equality operator. iterator == fixed_iterator.
//*****************************************************************************
template <typename TIterator>
bool operator ==(TIterator lhs,
const etl::fixed_iterator<TIterator>& rhs)
{
return lhs == rhs.get();
return lhs == TIterator(rhs);
}
//*****************************************************************************
/// Inequality operator. fixed_iterator == fixed_iterator.
//*****************************************************************************
template <typename TIterator>
bool operator !=(const etl::fixed_iterator<TIterator>& lhs,
@ -205,6 +253,8 @@ bool operator !=(const etl::fixed_iterator<TIterator>& lhs,
return !(lhs == rhs);
}
//*****************************************************************************
/// Inequality operator. fixed_iterator == iterator.
//*****************************************************************************
template <typename TIterator>
bool operator !=(const etl::fixed_iterator<TIterator>& lhs,
@ -213,6 +263,8 @@ bool operator !=(const etl::fixed_iterator<TIterator>& lhs,
return !(lhs == rhs);
}
//*****************************************************************************
/// Inequality operator. iterator == fixed_iterator.
//*****************************************************************************
template <typename TIterator>
bool operator !=(TIterator& lhs,

115
flat_multimap.h Normal file
View File

@ -0,0 +1,115 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
Copyright(c) 2015 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef __ETL_FLAT_MULTMAP__
#define __ETL_FLAT_MULTMAP__
#include <stddef.h>
#include <iterator>
#include <functional>
#include "iflat_multimap.h"
#include "vector.h"
//*****************************************************************************
///\defgroup flat_multimap flat_multimap
/// A flat_multimapmap with the capacity defined at compile time.
/// Has insertion of O(N) and find of O(logN)
/// Duplicate entries and not allowed.
///\ingroup containers
//*****************************************************************************
namespace etl
{
template <typename TKey, typename TValue, const size_t MAX_SIZE_, typename TCompare = std::less<TKey>>
//***************************************************************************
/// A flat_multimap implementation that uses a fixed size buffer.
///\tparam TKey The key type.
///\tparam TValue The value type.
///\tparam TCompare The type to compare keys. Default = std::less<TKey>
///\tparam MAX_SIZE_ The maximum number of elements that can be stored.
///\ingroup flat_multimap
//***************************************************************************
class flat_multimap : public iflat_multimap<TKey, TValue, TCompare>
{
public:
static const size_t MAX_SIZE = MAX_SIZE_;
//*************************************************************************
/// Constructor.
//*************************************************************************
flat_multimap()
: iflat_multimap<TKey, TValue, TCompare>(buffer)
{
}
//*************************************************************************
/// Copy constructor.
//*************************************************************************
flat_multimap(const flat_multimap& other)
: iflat_multimap<TKey, TValue, TCompare>(buffer)
{
iflat_multimap<TKey, TValue, TCompare>::assign(other.cbegin(), other.cend());
}
//*************************************************************************
/// Constructor, from an iterator range.
///\tparam TIterator The iterator type.
///\param first The iterator to the first element.
///\param last The iterator to the last element + 1.
//*************************************************************************
template <typename TIterator>
flat_multimap(TIterator first, TIterator last)
: iflat_multimap<TKey, TValue, TCompare>(buffer)
{
iflat_multimap<TKey, TValue, TCompare>::insert(first, last);
}
//*************************************************************************
/// Assignment operator.
//*************************************************************************
flat_multimap& operator = (const flat_multimap& rhs)
{
if (&rhs != this)
{
iflat_multimap<TKey, TValue, TCompare>::clear();
iflat_multimap<TKey, TValue, TCompare>::insert(rhs.cbegin(), rhs.cend());
}
return *this;
}
private:
etl::vector<typename iflat_multimap<TKey, TValue, TCompare>::value_type, MAX_SIZE> buffer; ///<The vector that stores the elements.
};
}
#endif

182
flat_multimap_base.h Normal file
View File

@ -0,0 +1,182 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
Copyright(c) 2015 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef __ETL_IN_IFLAT_MULTIMAP_H__
#error This header is a private element of etl::flat_multimap & etl::iflat_multimap
#endif
#ifndef __ETL_FLAT_MULTIMAP_BASE__
#define __ETL_FLAT_MULTIMAP_BASE__
#include <stddef.h>
#include "exception.h"
#include "ivector.h"
#ifndef ETL_THROW_EXCEPTIONS
#include "error_handler.h"
#endif
namespace etl
{
//***************************************************************************
///\ingroup flat_multimap
/// Exception base for flat_multimaps
//***************************************************************************
class flat_multimap_exception : public exception
{
public:
flat_multimap_exception(const char* what)
: exception(what)
{
}
};
//***************************************************************************
///\ingroup flat_multimap
/// Vector full exception.
//***************************************************************************
class flat_multimap_full : public flat_multimap_exception
{
public:
flat_multimap_full()
: flat_multimap_exception("flat_multimap: full")
{
}
};
//***************************************************************************
///\ingroup flat_multimap
/// Vector out of bounds exception.
//***************************************************************************
class flat_multimap_out_of_bounds : public flat_multimap_exception
{
public:
flat_multimap_out_of_bounds()
: flat_multimap_exception("flat_multimap: out of bounds")
{
}
};
//***************************************************************************
///\ingroup flat_multimap
/// Vector iterator exception.
//***************************************************************************
class flat_multimap_iterator : public flat_multimap_exception
{
public:
flat_multimap_iterator()
: flat_multimap_exception("flat_multimap: iterator error")
{
}
};
//***************************************************************************
///\ingroup flat_multimap
/// The base class for all templated flat_multimap types.
//***************************************************************************
class flat_multimap_base
{
public:
typedef size_t size_type;
//*************************************************************************
/// Gets the current size of the flat_multimap.
///\return The current size of the flat_multimap.
//*************************************************************************
size_type size() const
{
return vbase.size();
}
//*************************************************************************
/// Checks the 'empty' state of the flat_multimap.
///\return <b>true</b> if empty.
//*************************************************************************
bool empty() const
{
return vbase.empty();
}
//*************************************************************************
/// Checks the 'full' state of the flat_multimap.
///\return <b>true</b> if full.
//*************************************************************************
bool full() const
{
return vbase.full();
}
//*************************************************************************
/// Returns the capacity of the flat_multimap.
///\return The capacity of the flat_multimap.
//*************************************************************************
size_type capacity() const
{
return vbase.capacity();
}
//*************************************************************************
/// Returns the maximum possible size of the flat_multimap.
///\return The maximum size of the flat_multimap.
//*************************************************************************
size_type max_size() const
{
return vbase.max_size();
}
//*************************************************************************
/// Returns the remaining capacity.
///\return The remaining capacity.
//*************************************************************************
size_t available() const
{
return vbase.available();
}
protected:
//*************************************************************************
/// Constructor.
//*************************************************************************
flat_multimap_base(vector_base& vbase)
: vbase(vbase)
{
}
vector_base& vbase;
};
}
#endif

114
flat_multiset.h Normal file
View File

@ -0,0 +1,114 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
Copyright(c) 2015 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef __ETL_FLAT_MULTISET__
#define __ETL_FLAT_MULTISET__
#include <stddef.h>
#include <iterator>
#include <functional>
#include "iflat_multiset.h"
#include "vector.h"
//*****************************************************************************
///\defgroup flat_multiset flat_multiset
/// A flat_multiset with the capacity defined at compile time.
/// Has insertion of O(N) and flat_multiset of O(logN)
/// Duplicate entries and not allowed.
///\ingroup containers
//*****************************************************************************
namespace etl
{
template <typename T, const size_t MAX_SIZE_, typename TCompare = std::less<T>>
//***************************************************************************
/// A flat_multiset implementation that uses a fixed size buffer.
///\tparam T The value type.
///\tparam TCompare The type to compare keys. Default = std::less<T>
///\tparam MAX_SIZE_ The maximum number of elements that can be stored.
///\ingroup flat_multiset
//***************************************************************************
class flat_multiset : public iflat_multiset<T, TCompare>
{
public:
static const size_t MAX_SIZE = MAX_SIZE_;
//*************************************************************************
/// Constructor.
//*************************************************************************
flat_multiset()
: iflat_multiset<T, TCompare>(buffer)
{
}
//*************************************************************************
/// Copy constructor.
//*************************************************************************
flat_multiset(const flat_multiset& other)
: iflat_multiset<T, TCompare>(buffer)
{
iflat_multiset<T, TCompare>::assign(other.cbegin(), other.cend());
}
//*************************************************************************
/// Constructor, from an iterator range.
///\tparam TIterator The iterator type.
///\param first The iterator to the first element.
///\param last The iterator to the last element + 1.
//*************************************************************************
template <typename TIterator>
flat_multiset(TIterator first, TIterator last)
: iflat_multiset<T, TCompare>(buffer)
{
iflat_multiset<T, TCompare>::insert(first, last);
}
//*************************************************************************
/// Assignment operator.
//*************************************************************************
flat_multiset& operator = (const flat_multiset& rhs)
{
if (&rhs != this)
{
iflat_multiset<T, TCompare>::clear();
iflat_multiset<T, TCompare>::insert(rhs.cbegin(), rhs.cend());
}
return *this;
}
private:
etl::vector<T, MAX_SIZE> buffer; ///<The vector that stores the elements.
};
}
#endif

179
flat_multiset_base.h Normal file
View File

@ -0,0 +1,179 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
Copyright(c) 2015 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef __ETL_IN_IFLAT_MULTISET_H__
#error This header is a private element of etl::flat_multiset & etl::iflat_multiset
#endif
#ifndef __ETL_FLAT_MULTISET_BASE__
#define __ETL_FLAT_MULTISET_BASE__
#include <stddef.h>
#include "exception.h"
#include "ivector.h"
#include "error_handler.h"
namespace etl
{
//***************************************************************************
///\ingroup flat_multiset
/// Exception base for flat_multisets
//***************************************************************************
class flat_multiset_exception : public exception
{
public:
flat_multiset_exception(const char* what)
: exception(what)
{
}
};
//***************************************************************************
///\ingroup flat_multiset
/// Flat multiset full exception.
//***************************************************************************
class flat_multiset_full : public flat_multiset_exception
{
public:
flat_multiset_full()
: flat_multiset_exception("flat_multiset: full")
{
}
};
//***************************************************************************
///\ingroup flat_multiset
/// Flat multiset out of bounds exception.
//***************************************************************************
class flat_multiset_out_of_bounds : public flat_multiset_exception
{
public:
flat_multiset_out_of_bounds()
: flat_multiset_exception("flat_multiset: out of bounds")
{
}
};
//***************************************************************************
///\ingroup flat_multiset
/// Vector iterator exception.
//***************************************************************************
class flat_multiset_iterator : public flat_multiset_exception
{
public:
flat_multiset_iterator()
: flat_multiset_exception("flat_multiset: iterator error")
{
}
};
//***************************************************************************
///\ingroup flat_multiset
/// The base class for all templated flat_multiset types.
//***************************************************************************
class flat_multiset_base
{
public:
typedef size_t size_type;
//*************************************************************************
/// Gets the current size of the flat_multiset.
///\return The current size of the flat_multiset.
//*************************************************************************
size_type size() const
{
return vbase.size();
}
//*************************************************************************
/// Checks the 'empty' state of the flat_multiset.
///\return <b>true</b> if empty.
//*************************************************************************
bool empty() const
{
return vbase.empty();
}
//*************************************************************************
/// Checks the 'full' state of the flat_multiset.
///\return <b>true</b> if full.
//*************************************************************************
bool full() const
{
return vbase.full();
}
//*************************************************************************
/// Returns the capacity of the flat_multiset.
///\return The capacity of the flat_multiset.
//*************************************************************************
size_type capacity() const
{
return vbase.capacity();
}
//*************************************************************************
/// Returns the maximum possible size of the flat_multiset.
///\return The maximum size of the flat_multiset.
//*************************************************************************
size_type max_size() const
{
return vbase.max_size();
}
//*************************************************************************
/// Returns the remaining capacity.
///\return The remaining capacity.
//*************************************************************************
size_t available() const
{
return vbase.available();
}
protected:
//*************************************************************************
/// Constructor.
//*************************************************************************
flat_multiset_base(vector_base& vbase)
: vbase(vbase)
{
}
vector_base& vbase;
};
}
#endif

155
fnv_1.h
View File

@ -34,7 +34,6 @@ SOFTWARE.
#include "static_assert.h"
#include "type_traits.h"
#include "endian.h"
#include "ihash.h"
#if defined(COMPILER_KEIL)
@ -48,11 +47,9 @@ namespace etl
{
//***************************************************************************
/// Calculates the fnv_1_64 hash.
///\tparam ENDIANNESS The endianness of the calculation for input types larger than uint8_t. Default = endian::little.
///\ingroup fnv_1_64
//***************************************************************************
template <const int ENDIANNESS = endian::little>
class fnv_1_64 : public etl::ihash
class fnv_1_64
{
public:
@ -62,7 +59,6 @@ namespace etl
/// Default constructor.
//*************************************************************************
fnv_1_64()
: ihash(etl::endian(ENDIANNESS))
{
reset();
}
@ -74,10 +70,15 @@ namespace etl
//*************************************************************************
template<typename TIterator>
fnv_1_64(TIterator begin, const TIterator end)
: ihash(etl::endian(ENDIANNESS))
{
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
reset();
add(begin, end);
while (begin != end)
{
hash *= PRIME;
hash ^= *begin++;
}
}
//*************************************************************************
@ -96,17 +97,13 @@ namespace etl
template<typename TIterator>
void add(TIterator begin, const TIterator end)
{
ihash::add(begin, end);
}
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
//*************************************************************************
/// Adds a value.
/// \param value The value to add to the checksum.
//*************************************************************************
template<typename TValue>
void add(TValue value)
{
ihash::add(value);
while (begin != end)
{
hash *= PRIME;
hash ^= *begin++;
}
}
//*************************************************************************
@ -134,14 +131,6 @@ namespace etl
return hash;
}
//*************************************************************************
/// Gets the generic digest value.
//*************************************************************************
generic_digest digest() const
{
return ihash::get_digest(hash);
}
private:
value_type hash;
@ -152,11 +141,9 @@ namespace etl
//***************************************************************************
/// Calculates the fnv_1a_64 hash.
///\tparam ENDIANNESS The endianness of the calculation for input types larger than uint8_t. Default = endian::little.
///\ingroup fnv_1a_64
//***************************************************************************
template <const int ENDIANNESS = endian::little>
class fnv_1a_64 : public etl::ihash
class fnv_1a_64
{
public:
@ -166,7 +153,6 @@ namespace etl
/// Default constructor.
//*************************************************************************
fnv_1a_64()
: ihash(etl::endian(ENDIANNESS))
{
reset();
}
@ -178,10 +164,15 @@ namespace etl
//*************************************************************************
template<typename TIterator>
fnv_1a_64(TIterator begin, const TIterator end)
: ihash(etl::endian(ENDIANNESS))
{
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
reset();
add(begin, end);
while (begin != end)
{
hash ^= *begin++;
hash *= PRIME;
}
}
//*************************************************************************
@ -200,17 +191,13 @@ namespace etl
template<typename TIterator>
void add(TIterator begin, const TIterator end)
{
ihash::add(begin, end);
}
//*************************************************************************
/// Adds a value.
/// \param value The value to add to the checksum.
//*************************************************************************
template<typename TValue>
void add(TValue value)
{
ihash::add(value);
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
while (begin != end)
{
hash ^= *begin++;
hash *= PRIME;
}
}
//*************************************************************************
@ -238,14 +225,6 @@ namespace etl
return hash;
}
//*************************************************************************
/// Gets the generic digest value.
//*************************************************************************
generic_digest digest() const
{
return ihash::get_digest(hash);
}
private:
value_type hash;
@ -256,11 +235,9 @@ namespace etl
//***************************************************************************
/// Calculates the fnv_1_32 hash.
///\tparam ENDIANNESS The endianness of the calculation for input types larger than uint8_t. Default = endian::little.
///\ingroup fnv_1_32
//***************************************************************************
template <const int ENDIANNESS = endian::little>
class fnv_1_32 : public etl::ihash
class fnv_1_32
{
public:
@ -270,7 +247,6 @@ namespace etl
/// Default constructor.
//*************************************************************************
fnv_1_32()
: ihash(etl::endian(ENDIANNESS))
{
reset();
}
@ -282,10 +258,15 @@ namespace etl
//*************************************************************************
template<typename TIterator>
fnv_1_32(TIterator begin, const TIterator end)
: ihash(etl::endian(ENDIANNESS))
{
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
reset();
add(begin, end);
while (begin != end)
{
hash *= PRIME;
hash ^= *begin++;
}
}
//*************************************************************************
@ -304,17 +285,13 @@ namespace etl
template<typename TIterator>
void add(TIterator begin, const TIterator end)
{
ihash::add(begin, end);
}
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
//*************************************************************************
/// Adds a value.
/// \param value The value to add to the checksum.
//*************************************************************************
template<typename TValue>
void add(TValue value)
{
ihash::add(value);
while (begin != end)
{
hash *= PRIME;
hash ^= *begin++;
}
}
//*************************************************************************
@ -342,14 +319,6 @@ namespace etl
return hash;
}
//*************************************************************************
/// Gets the generic digest value.
//*************************************************************************
generic_digest digest() const
{
return ihash::get_digest(hash);
}
private:
value_type hash;
@ -360,11 +329,9 @@ namespace etl
//***************************************************************************
/// Calculates the fnv_1a_32 hash.
///\tparam ENDIANNESS The endianness of the calculation for input types larger than uint8_t. Default = endian::little.
///\ingroup fnv_1a_32
//***************************************************************************
template <const int ENDIANNESS = endian::little>
class fnv_1a_32 : public etl::ihash
class fnv_1a_32
{
public:
@ -374,7 +341,6 @@ namespace etl
/// Default constructor.
//*************************************************************************
fnv_1a_32()
: ihash(etl::endian(ENDIANNESS))
{
reset();
}
@ -386,10 +352,15 @@ namespace etl
//*************************************************************************
template<typename TIterator>
fnv_1a_32(TIterator begin, const TIterator end)
: ihash(etl::endian(ENDIANNESS))
{
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
reset();
add(begin, end);
while (begin != end)
{
hash ^= *begin++;
hash *= PRIME;
}
}
//*************************************************************************
@ -408,17 +379,13 @@ namespace etl
template<typename TIterator>
void add(TIterator begin, const TIterator end)
{
ihash::add(begin, end);
}
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
//*************************************************************************
/// Adds a value.
/// \param value The value to add to the checksum.
//*************************************************************************
template<typename TValue>
void add(TValue value)
{
ihash::add(value);
while (begin != end)
{
hash ^= *begin++;
hash *= PRIME;
}
}
//*************************************************************************
@ -446,14 +413,6 @@ namespace etl
return hash;
}
//*************************************************************************
/// Gets the generic digest value.
//*************************************************************************
generic_digest digest() const
{
return ihash::get_digest(hash);
}
private:
value_type hash;

4
hash.h
View File

@ -51,7 +51,7 @@ namespace etl
typename enable_if<sizeof(T) == sizeof(uint32_t), size_t>::type
generic_hash(uint8_t* begin, uint8_t* end)
{
return fnv_1a_32<>(begin, end);
return fnv_1a_32(begin, end);
}
//*************************************************************************
@ -61,7 +61,7 @@ namespace etl
typename enable_if<sizeof(T) == sizeof(uint64_t), size_t>::type
generic_hash(uint8_t* begin, uint8_t* end)
{
return fnv_1a_64<>(begin, end);
return fnv_1a_64(begin, end);
}
}

View File

@ -223,10 +223,11 @@ namespace etl
{
iterator i_element = lower_bound(key);
if (i_element->first != key)
if (i_element == end())
{
// Doesn't exist, so create a new one.
i_element = insert(std::make_pair(key, mapped_type())).first;
value_type value(key, mapped_type());
i_element = insert(value).first;
}
return i_element->second;
@ -245,12 +246,7 @@ namespace etl
if (i_element == end())
{
// Doesn't exist.
#if ETL_THROW_EXCEPTIONS
throw flat_map_out_of_bounds();
#else
error_handler::error(flat_map_out_of_bounds());
#endif
ETL_ERROR(flat_map_out_of_bounds());
}
return i_element->second;
@ -269,12 +265,7 @@ namespace etl
if (i_element == end())
{
// Doesn't exist.
#if ETL_THROW_EXCEPTIONS
throw flat_map_out_of_bounds();
#else
error_handler::error(flat_map_out_of_bounds());
#endif
ETL_ERROR(flat_map_out_of_bounds());
}
return i_element->second;
@ -295,11 +286,7 @@ namespace etl
if (count < 0)
{
#ifdef ETL_THROW_EXCEPTIONS
throw flat_map_iterator();
#else
error_handler::error(flat_map_iterator());
#endif
ETL_ERROR(flat_map_iterator());
}
#endif
@ -327,11 +314,7 @@ namespace etl
// At the end.
if (buffer.full())
{
#ifdef ETL_THROW_EXCEPTIONS
throw flat_map_full();
#else
error_handler::error(flat_map_full());
#endif
ETL_ERROR(flat_map_full());
}
else
{
@ -356,11 +339,7 @@ namespace etl
// A new one.
if (buffer.full())
{
#ifdef ETL_THROW_EXCEPTIONS
throw flat_map_full();
#else
error_handler::error(flat_map_full());
#endif
ETL_ERROR(flat_map_full());
}
else
{
@ -375,8 +354,8 @@ namespace etl
}
//*********************************************************************
/// Inserts a value to the flat_set.
/// If ETL_THROW_EXCEPTIONS is defined, emits flat_set_full if the flat_set is already full.
/// Inserts a value to the flat_map.
/// If ETL_THROW_EXCEPTIONS is defined, emits flat_map_full if the flat_map is already full.
///\param position The position to insert at.
///\param value The value to insert.
//*********************************************************************

494
iflat_multimap.h Normal file
View File

@ -0,0 +1,494 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
Copyright(c) 2015 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef __ETL_IFLAT_MULTIMAP__
#define __ETL_IFLAT_MULTIMAP__
#define __ETL_IN_IFLAT_MULTIMAP_H__
#include <iterator>
#include <algorithm>
#include <functional>
#include <utility>
#include <stddef.h>
#include "flat_multimap_base.h"
#include "type_traits.h"
#include "parameter_type.h"
#include "ivector.h"
#include "error_handler.h"
namespace etl
{
//***************************************************************************
/// The base class for specifically sized flat_multimaps.
/// Can be used as a reference type for all flat_multimaps containing a specific type.
///\ingroup flat_multimap
//***************************************************************************
template <typename TKey, typename TMapped, typename TKeyCompare = std::less<TKey>>
class iflat_multimap : public flat_multimap_base
{
public:
typedef std::pair<TKey, TMapped> value_type;
private:
typedef etl::ivector<value_type> buffer_t;
public:
typedef TKey key_type;
typedef TMapped mapped_type;
typedef TKeyCompare key_compare;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef typename buffer_t::iterator iterator;
typedef typename buffer_t::const_iterator const_iterator;
typedef typename buffer_t::reverse_iterator reverse_iterator;
typedef typename buffer_t::const_reverse_iterator const_reverse_iterator;
typedef size_t size_type;
typedef typename std::iterator_traits<iterator>::difference_type difference_type;
protected:
typedef typename parameter_type<TKey>::type key_value_parameter_t;
private:
//*********************************************************************
/// How to compare elements and keys.
//*********************************************************************
class compare
{
public:
bool operator ()(const value_type& element, key_type key) const
{
return key_compare()(element.first, key);
}
bool operator ()(key_type key, const value_type& element) const
{
return key_compare()(key, element.first);
}
};
public:
//*********************************************************************
/// Returns an iterator to the beginning of the flat_multimap.
///\return An iterator to the beginning of the flat_multimap.
//*********************************************************************
iterator begin()
{
return buffer.begin();
}
//*********************************************************************
/// Returns a const_iterator to the beginning of the flat_multimap.
///\return A const iterator to the beginning of the flat_multimap.
//*********************************************************************
const_iterator begin() const
{
return buffer.begin();
}
//*********************************************************************
/// Returns an iterator to the end of the flat_multimap.
///\return An iterator to the end of the flat_multimap.
//*********************************************************************
iterator end()
{
return buffer.end();
}
//*********************************************************************
/// Returns a const_iterator to the end of the flat_multimap.
///\return A const iterator to the end of the flat_multimap.
//*********************************************************************
const_iterator end() const
{
return buffer.end();
}
//*********************************************************************
/// Returns a const_iterator to the beginning of the flat_multimap.
///\return A const iterator to the beginning of the flat_multimap.
//*********************************************************************
const_iterator cbegin() const
{
return buffer.cbegin();
}
//*********************************************************************
/// Returns a const_iterator to the end of the flat_multimap.
///\return A const iterator to the end of the flat_multimap.
//*********************************************************************
const_iterator cend() const
{
return buffer.cend();
}
//*********************************************************************
/// Returns an reverse iterator to the reverse beginning of the flat_multimap.
///\return Iterator to the reverse beginning of the flat_multimap.
//*********************************************************************
reverse_iterator rbegin()
{
return buffer.rbegin();
}
//*********************************************************************
/// Returns a const reverse iterator to the reverse beginning of the flat_multimap.
///\return Const iterator to the reverse beginning of the flat_multimap.
//*********************************************************************
const_reverse_iterator rbegin() const
{
return buffer.rbegin();
}
//*********************************************************************
/// Returns a reverse iterator to the end + 1 of the flat_multimap.
///\return Reverse iterator to the end + 1 of the flat_multimap.
//*********************************************************************
reverse_iterator rend()
{
return buffer.rend();
}
//*********************************************************************
/// Returns a const reverse iterator to the end + 1 of the flat_multimap.
///\return Const reverse iterator to the end + 1 of the flat_multimap.
//*********************************************************************
const_reverse_iterator rend() const
{
return buffer.rend();
}
//*********************************************************************
/// Returns a const reverse iterator to the reverse beginning of the flat_multimap.
///\return Const reverse iterator to the reverse beginning of the flat_multimap.
//*********************************************************************
const_reverse_iterator crbegin() const
{
return buffer.crbegin();
}
//*********************************************************************
/// Returns a const reverse iterator to the end + 1 of the flat_multimap.
///\return Const reverse iterator to the end + 1 of the flat_multimap.
//*********************************************************************
const_reverse_iterator crend() const
{
return buffer.crend();
}
//*********************************************************************
/// Assigns values to the flat_multimap.
/// If ETL_THROW_EXCEPTIONS is defined, emits flat_multimap_full if the flat_multimap does not have enough free space.
/// If ETL_THROW_EXCEPTIONS is defined, emits flat_multimap_iterator if the iterators are reversed.
///\param first The iterator to the first element.
///\param last The iterator to the last element + 1.
//*********************************************************************
template <typename TIterator>
void assign(TIterator first, TIterator last)
{
#ifdef _DEBUG
difference_type count = std::distance(first, last);
if (count < 0)
{
ETL_ERROR(flat_multimap_iterator());
return;
}
#endif
clear();
while (first != last)
{
insert(*first++);
}
}
//*********************************************************************
/// Inserts a value to the flat_multimap.
/// If ETL_THROW_EXCEPTIONS is defined, emits flat_multimap_full if the flat_multimap is already full.
///\param value The value to insert.
//*********************************************************************
std::pair<iterator, bool> insert(const value_type& value)
{
std::pair<iterator, bool> result(end(), false);
iterator i_element = lower_bound(value.first);
if (buffer.full())
{
ETL_ERROR(flat_multimap_full());
return result;
}
if (i_element == end())
{
// At the end.
buffer.push_back(value);
result.first = end() - 1;
result.second = true;
}
else
{
// Not at the end.
buffer.insert(i_element, value);
result.first = i_element;
result.second = true;
}
return result;
}
//*********************************************************************
/// Inserts a value to the flast_multi.
/// If ETL_THROW_EXCEPTIONS is defined, emits flat_map_full if the flat_map is already full.
///\param position The position to insert at.
///\param value The value to insert.
//*********************************************************************
iterator insert(iterator position, const value_type& value)
{
return insert(value).first;
}
//*********************************************************************
/// Inserts a range of values to the flat_multimap.
/// If ETL_THROW_EXCEPTIONS is defined, emits flat_multimap_full if the flat_multimap does not have enough free space.
///\param position The position to insert at.
///\param first The first element to add.
///\param last The last + 1 element to add.
//*********************************************************************
template <class TIterator>
void insert(TIterator first, TIterator last)
{
while (first != last)
{
insert(*first++);
}
}
//*********************************************************************
/// Erases an element.
///\param key The key to erase.
///\return The number of elements erased. 0 or 1.
//*********************************************************************
size_t erase(key_value_parameter_t key)
{
std::pair<iterator, iterator> range = equal_range(key);
if (range.first == end())
{
return 0;
}
else
{
size_t count = std::distance(range.first, range.second);
erase(range.first, range.second);
return count;
}
}
//*********************************************************************
/// Erases an element.
///\param i_element Iterator to the element.
//*********************************************************************
void erase(iterator i_element)
{
buffer.erase(i_element);
}
//*********************************************************************
/// Erases a range of elements.
/// The range includes all the elements between first and last, including the
/// element pointed by first, but not the one pointed by last.
///\param first Iterator to the first element.
///\param last Iterator to the last element.
//*********************************************************************
void erase(iterator first, iterator last)
{
buffer.erase(first, last);
}
//*************************************************************************
/// Clears the flat_multimap.
//*************************************************************************
void clear()
{
buffer.clear();
}
//*********************************************************************
/// Finds an element.
///\param key The key to search for.
///\return An iterator pointing to the element or end() if not found.
//*********************************************************************
iterator find(key_value_parameter_t key)
{
return lower_bound(key);
}
//*********************************************************************
/// Finds an element.
///\param key The key to search for.
///\return An iterator pointing to the element or end() if not found.
//*********************************************************************
const_iterator find(key_value_parameter_t key) const
{
return lower_bound(key);
}
//*********************************************************************
/// Counts an element.
///\param key The key to search for.
///\return 1 if the key exists, otherwise 0.
//*********************************************************************
size_t count(key_value_parameter_t key) const
{
std::pair<const_iterator, const_iterator> range = equal_range(key);
return std::distance(range.first, range.second);
}
//*********************************************************************
/// Finds the lower bound of a key
///\param key The key to search for.
///\return An iterator.
//*********************************************************************
iterator lower_bound(key_value_parameter_t key)
{
return std::lower_bound(begin(), end(), key, compare());
}
//*********************************************************************
/// Finds the lower bound of a key
///\param key The key to search for.
///\return An iterator.
//*********************************************************************
const_iterator lower_bound(key_value_parameter_t key) const
{
return std::lower_bound(cbegin(), cend(), key, compare());
}
//*********************************************************************
/// Finds the upper bound of a key
///\param key The key to search for.
///\return An iterator.
//*********************************************************************
iterator upper_bound(key_value_parameter_t key)
{
return std::upper_bound(begin(), end(), key, compare());
}
//*********************************************************************
/// Finds the upper bound of a key
///\param key The key to search for.
///\return An iterator.
//*********************************************************************
const_iterator upper_bound(key_value_parameter_t key) const
{
return std::upper_bound(begin(), end(), key, compare());
}
//*********************************************************************
/// Finds the range of equal elements of a key
///\param key The key to search for.
///\return An iterator pair.
//*********************************************************************
std::pair<iterator, iterator> equal_range(key_value_parameter_t key)
{
iterator i_lower = std::lower_bound(begin(), end(), key, compare());
return std::make_pair(i_lower, std::upper_bound(i_lower, end(), key, compare()));
}
//*********************************************************************
/// Finds the range of equal elements of a key
///\param key The key to search for.
///\return An iterator pair.
//*********************************************************************
std::pair<const_iterator, const_iterator> equal_range(key_value_parameter_t key) const
{
const_iterator i_lower = std::lower_bound(cbegin(), cend(), key, compare());
return std::make_pair(i_lower, std::upper_bound(i_lower, cend(), key, compare()));
}
protected:
//*********************************************************************
/// Constructor.
//*********************************************************************
iflat_multimap(buffer_t& buffer)
: flat_multimap_base(buffer),
buffer(buffer)
{
}
private:
buffer_t& buffer;
};
//***************************************************************************
/// Equal operator.
///\param lhs Reference to the first flat_multimap.
///\param rhs Reference to the second flat_multimap.
///\return <b>true</b> if the arrays are equal, otherwise <b>false</b>
///\ingroup flat_multimap
//***************************************************************************
template <typename TKey, typename TMapped, typename TKeyCompare>
bool operator ==(const etl::iflat_multimap<TKey, TMapped, TKeyCompare>& lhs, const etl::iflat_multimap<TKey, TMapped, TKeyCompare>& rhs)
{
return (lhs.size() == rhs.size()) && std::equal(lhs.begin(), lhs.end(), rhs.begin());
}
//***************************************************************************
/// Not equal operator.
///\param lhs Reference to the first flat_multimap.
///\param rhs Reference to the second flat_multimap.
///\return <b>true</b> if the arrays are not equal, otherwise <b>false</b>
///\ingroup flat_multimap
//***************************************************************************
template <typename TKey, typename TMapped, typename TKeyCompare>
bool operator !=(const etl::iflat_multimap<TKey, TMapped, TKeyCompare>& lhs, const etl::iflat_multimap<TKey, TMapped, TKeyCompare>& rhs)
{
return !(lhs == rhs);
}
}
#undef __ETL_IN_IFLAT_MULTIMAP_H__
#endif

465
iflat_multiset.h Normal file
View File

@ -0,0 +1,465 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
Copyright(c) 2015 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef __ETL_IFLAT_MULTISET__
#define __ETL_IFLAT_MULTISET__
#define __ETL_IN_IFLAT_MULTISET_H__
#include <iterator>
#include <algorithm>
#include <functional>
#include <utility>
#include <stddef.h>
#include "flat_multiset_base.h"
#include "type_traits.h"
#include "parameter_type.h"
#include "ivector.h"
#include "error_handler.h"
namespace etl
{
//***************************************************************************
/// The base class for specifically sized flat_multisets.
/// Can be used as a reference type for all flat_multisets containing a specific type.
///\ingroup flat_multiset
//***************************************************************************
template <typename T, typename TKeyCompare = std::less<T>>
class iflat_multiset : public flat_multiset_base
{
private:
typedef etl::ivector<T> buffer_t;
public:
typedef T key_type;
typedef T value_type;
typedef TKeyCompare key_compare;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef typename buffer_t::iterator iterator;
typedef typename buffer_t::const_iterator const_iterator;
typedef typename buffer_t::reverse_iterator reverse_iterator;
typedef typename buffer_t::const_reverse_iterator const_reverse_iterator;
typedef size_t size_type;
typedef typename std::iterator_traits<iterator>::difference_type difference_type;
protected:
typedef typename parameter_type<T>::type parameter_t;
public:
//*********************************************************************
/// Returns an iterator to the beginning of the flat_multiset.
///\return An iterator to the beginning of the flat_multiset.
//*********************************************************************
iterator begin()
{
return buffer.begin();
}
//*********************************************************************
/// Returns a const_iterator to the beginning of the flat_multiset.
///\return A const iterator to the beginning of the flat_multiset.
//*********************************************************************
const_iterator begin() const
{
return buffer.begin();
}
//*********************************************************************
/// Returns an iterator to the end of the flat_multiset.
///\return An iterator to the end of the flat_multiset.
//*********************************************************************
iterator end()
{
return buffer.end();
}
//*********************************************************************
/// Returns a const_iterator to the end of the flat_multiset.
///\return A const iterator to the end of the flat_multiset.
//*********************************************************************
const_iterator end() const
{
return buffer.end();
}
//*********************************************************************
/// Returns a const_iterator to the beginning of the flat_multiset.
///\return A const iterator to the beginning of the flat_multiset.
//*********************************************************************
const_iterator cbegin() const
{
return buffer.cbegin();
}
//*********************************************************************
/// Returns a const_iterator to the end of the flat_multiset.
///\return A const iterator to the end of the flat_multiset.
//*********************************************************************
const_iterator cend() const
{
return buffer.cend();
}
//*********************************************************************
/// Returns an reverse iterator to the reverse beginning of the flat_multiset.
///\return Iterator to the reverse beginning of the flat_multiset.
//*********************************************************************
reverse_iterator rbegin()
{
return buffer.rbegin();
}
//*********************************************************************
/// Returns a const reverse iterator to the reverse beginning of the flat_multiset.
///\return Const iterator to the reverse beginning of the flat_multiset.
//*********************************************************************
const_reverse_iterator rbegin() const
{
return buffer.rbegin();
}
//*********************************************************************
/// Returns a reverse iterator to the end + 1 of the flat_multiset.
///\return Reverse iterator to the end + 1 of the flat_multiset.
//*********************************************************************
reverse_iterator rend()
{
return buffer.rend();
}
//*********************************************************************
/// Returns a const reverse iterator to the end + 1 of the flat_multiset.
///\return Const reverse iterator to the end + 1 of the flat_multiset.
//*********************************************************************
const_reverse_iterator rend() const
{
return buffer.rend();
}
//*********************************************************************
/// Returns a const reverse iterator to the reverse beginning of the flat_multiset.
///\return Const reverse iterator to the reverse beginning of the flat_multiset.
//*********************************************************************
const_reverse_iterator crbegin() const
{
return buffer.crbegin();
}
//*********************************************************************
/// Returns a const reverse iterator to the end + 1 of the flat_multiset.
///\return Const reverse iterator to the end + 1 of the flat_multiset.
//*********************************************************************
const_reverse_iterator crend() const
{
return buffer.crend();
}
//*********************************************************************
/// Assigns values to the flat_multiset.
/// If ETL_THROW_EXCEPTIONS is defined, emits flat_multiset_full if the flat_multiset does not have enough free space.
/// If ETL_THROW_EXCEPTIONS is defined, emits flat_multiset_iterator if the iterators are reversed.
///\param first The iterator to the first element.
///\param last The iterator to the last element + 1.
//*********************************************************************
template <typename TIterator>
void assign(TIterator first, TIterator last)
{
#ifdef _DEBUG
difference_type count = std::distance(first, last);
if (count < 0)
{
ETL_ERROR(flat_multiset_iterator());
}
#endif
clear();
while (first != last)
{
insert(*first++);
}
}
//*********************************************************************
/// Inserts a value to the flat_multiset.
/// If ETL_THROW_EXCEPTIONS is defined, emits flat_multiset_full if the flat_multiset is already full.
///\param value The value to insert.
//*********************************************************************
std::pair<iterator, bool> insert(parameter_t value)
{
std::pair<iterator, bool> result(end(), false);
if (buffer.full())
{
ETL_ERROR(flat_multiset_full());
return result;
}
iterator i_element = std::lower_bound(begin(), end(), value, TKeyCompare());
if (i_element == end())
{
// At the end.
buffer.push_back(value);
result.first = end() - 1;
result.second = true;
}
else
{
// Not at the end.
buffer.insert(i_element, value);
result.first = i_element;
result.second = true;
}
return result;
}
//*********************************************************************
/// Inserts a value to the flat_multiset.
/// If ETL_THROW_EXCEPTIONS is defined, emits flat_multiset_full if the flat_multiset is already full.
///\param position The position to insert at.
///\param value The value to insert.
//*********************************************************************
iterator insert(iterator position, parameter_t value)
{
return insert(value).first;
}
//*********************************************************************
/// Inserts a range of values to the flat_multiset.
/// If ETL_THROW_EXCEPTIONS is defined, emits flat_multiset_full if the flat_multiset does not have enough free space.
///\param position The position to insert at.
///\param first The first element to add.
///\param last The last + 1 element to add.
//*********************************************************************
template <class TIterator>
void insert(TIterator first, TIterator last)
{
while (first != last)
{
insert(*first++);
}
}
//*********************************************************************
/// Erases an element.
///\param key The key to erase.
///\return The number of elements erased. 0 or 1.
//*********************************************************************
size_t erase(parameter_t key)
{
std::pair<iterator, iterator> range = equal_range(key);
if (range.first == end())
{
return 0;
}
else
{
size_t count = std::distance(range.first, range.second);
erase(range.first, range.second);
return count;
}
}
//*********************************************************************
/// Erases an element.
///\param i_element Iterator to the element.
//*********************************************************************
void erase(iterator i_element)
{
buffer.erase(i_element);
}
//*********************************************************************
/// Erases a range of elements.
/// The range includes all the elements between first and last, including the
/// element pointed by first, but not the one pointed by last.
///\param first Iterator to the first element.
///\param last Iterator to the last element.
//*********************************************************************
void erase(iterator first, iterator last)
{
buffer.erase(first, last);
}
//*************************************************************************
/// Clears the flat_multiset.
//*************************************************************************
void clear()
{
buffer.clear();
}
//*********************************************************************
/// Finds an element.
///\param key The key to search for.
///\return An iterator pointing to the element or end() if not found.
//*********************************************************************
iterator find(parameter_t key)
{
return std::lower_bound(begin(), end(), key, TKeyCompare());
}
//*********************************************************************
/// Finds an element.
///\param key The key to search for.
///\return An iterator pointing to the element or end() if not found.
//*********************************************************************
const_iterator find(parameter_t key) const
{
return std::lower_bound(begin(), end(), key, TKeyCompare());
}
//*********************************************************************
/// Counts an element.
///\param key The key to search for.
///\return 1 if the key exists, otherwise 0.
//*********************************************************************
size_t count(parameter_t key) const
{
std::pair<const_iterator, const_iterator> range = equal_range(key);
return std::distance(range.first, range.second);
}
//*********************************************************************
/// Finds the lower bound of a key
///\param key The key to search for.
///\return An iterator.
//*********************************************************************
iterator lower_bound(parameter_t key)
{
return std::lower_bound(begin(), end(), key, TKeyCompare());
}
//*********************************************************************
/// Finds the lower bound of a key
///\param key The key to search for.
///\return An iterator.
//*********************************************************************
const_iterator lower_bound(parameter_t key) const
{
return std::lower_bound(cbegin(), cend(), key, TKeyCompare());
}
//*********************************************************************
/// Finds the upper bound of a key
///\param key The key to search for.
///\return An iterator.
//*********************************************************************
iterator upper_bound(parameter_t key)
{
return std::upper_bound(begin(), end(), key, TKeyCompare());
}
//*********************************************************************
/// Finds the upper bound of a key
///\param key The key to search for.
///\return An iterator.
//*********************************************************************
const_iterator upper_bound(parameter_t key) const
{
return std::upper_bound(cbegin(), cend(), key, TKeyCompare());
}
//*********************************************************************
/// Finds the range of equal elements of a key
///\param key The key to search for.
///\return An iterator pair.
//*********************************************************************
std::pair<iterator, iterator> equal_range(parameter_t key)
{
return std::equal_range(begin(), end(), key, TKeyCompare());
}
//*********************************************************************
/// Finds the range of equal elements of a key
///\param key The key to search for.
///\return An iterator pair.
//*********************************************************************
std::pair<const_iterator, const_iterator> equal_range(parameter_t key) const
{
return std::equal_range(cbegin(), cend(), key, TKeyCompare());
}
protected:
//*********************************************************************
/// Constructor.
//*********************************************************************
iflat_multiset(buffer_t& buffer)
: flat_multiset_base(buffer),
buffer(buffer)
{
}
private:
buffer_t& buffer;
};
//***************************************************************************
/// Equal operator.
///\param lhs Reference to the first flat_multiset.
///\param rhs Reference to the second flat_multiset.
///\return <b>true</b> if the arrays are equal, otherwise <b>false</b>
///\ingroup flat_multiset
//***************************************************************************
template <typename T, typename TKeyCompare>
bool operator ==(const etl::iflat_multiset<T, TKeyCompare>& lhs, const etl::iflat_multiset<T, TKeyCompare>& rhs)
{
return (lhs.size() == rhs.size()) && std::equal(lhs.begin(), lhs.end(), rhs.begin());
}
//***************************************************************************
/// Not equal operator.
///\param lhs Reference to the first flat_multiset.
///\param rhs Reference to the second flat_multiset.
///\return <b>true</b> if the arrays are not equal, otherwise <b>false</b>
///\ingroup flat_multiset
//***************************************************************************
template <typename T, typename TKeyCompare>
bool operator !=(const etl::iflat_multiset<T, TKeyCompare>& lhs, const etl::iflat_multiset<T, TKeyCompare>& rhs)
{
return !(lhs == rhs);
}
}
#undef __ETL_IN_IFLAT_MULTISET_H__
#endif

View File

@ -41,10 +41,7 @@ SOFTWARE.
#include "type_traits.h"
#include "parameter_type.h"
#include "ivector.h"
#ifndef ETL_THROW_EXCEPTIONS
#include "error_handler.h"
#endif
namespace etl
{
@ -205,11 +202,7 @@ namespace etl
if (count < 0)
{
#ifdef ETL_THROW_EXCEPTIONS
throw flat_set_iterator();
#else
error_handler::error(flat_set_iterator());
#endif
ETL_ERROR(flat_set_iterator());
}
#endif
@ -230,54 +223,27 @@ namespace etl
{
std::pair<iterator, bool> result(end(), false);
iterator i_element = std::lower_bound(begin(), end(), value, TKeyCompare());
if (buffer.full())
{
ETL_ERROR(flat_set_full());
return result;
}
iterator i_element = std::lower_bound(begin(), end(), value, TKeyCompare());
if (i_element == end())
if (i_element == end())
{
// At the end.
if (buffer.full())
{
#ifdef ETL_THROW_EXCEPTIONS
throw flat_set_full();
#else
error_handler::error(flat_set_full());
#endif
}
else
{
buffer.push_back(value);
result.first = end() - 1;
result.second = true;
}
buffer.push_back(value);
result.first = end() - 1;
result.second = true;
}
else
{
// Not at the end.
// Existing element?
if (value == *i_element)
{
// Yes.
result.first = i_element;
result.second = false;
}
else
{
// A new one.
if (buffer.full())
{
#ifdef ETL_THROW_EXCEPTIONS
throw flat_set_full();
#else
error_handler::error(flat_set_full());
#endif
}
else
{
buffer.insert(i_element, value);
result.first = i_element;
result.second = true;
}
}
buffer.insert(i_element, value);
result.first = i_element;
result.second = true;
}
return result;

131
ihash.h
View File

@ -34,9 +34,8 @@ SOFTWARE.
#include <utility>
#include "exception.h"
#include "endian.h"
///\defgroup ihash Base class for all hash type classes.
///\defgroup ihash Common data for all hash type classes.
///\ingroup hash
namespace etl
@ -69,134 +68,6 @@ namespace etl
/// For the Americans
typedef hash_finalised hash_finalized;
//***************************************************************************
/// Hash algorithm base class.
/// \ingroup ihash
//***************************************************************************
class ihash
{
public:
/// Generic return type.
typedef std::pair<const uint8_t*, const uint8_t*> generic_digest;
//*************************************************************************
/// Default constructor.
/// \param endianness The endianness to use for integral types larger than uint8_t.
//*************************************************************************
ihash(etl::endian endianness)
: endianness(endianness)
{
}
//*************************************************************************
/// \param value The value to add to the hash.
//*************************************************************************
template<typename TValue>
void add(TValue value)
{
uint8_t* p_data = reinterpret_cast<uint8_t*>(&value);
if (endianness == endian::little)
{
for (int i = 0; i < sizeof(TValue); ++i)
{
add(p_data[i]);
}
}
else
{
for (int i = sizeof(TValue) - 1; i >= 0; --i)
{
add(p_data[i]);
}
}
}
//*************************************************************************
/// \param begin Start of the range.
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
void add(TIterator begin, const TIterator end)
{
while (begin != end)
{
add(*begin);
++begin;
}
}
//*************************************************************************
/// \param value The value to add to the checksum.
//*************************************************************************
template<typename TValue>
ihash& operator +=(TValue value)
{
add(value);
return *this;
}
//*************************************************************************
/// Get the endianness.
//*************************************************************************
etl::endian endian() const
{
return endianness;
}
//*************************************************************************
/// Set the endianness.
//*************************************************************************
void endian(etl::endian e)
{
endianness = e;
}
//*************************************************************************
/// \param value The uint8_t to add to the hash.
//*************************************************************************
virtual void add(uint8_t value) = 0;
//*************************************************************************
/// Resets the hash to the initial state.
//*************************************************************************
virtual void reset() = 0;
//*************************************************************************
/// Gets the result as a generic digest.
//*************************************************************************
virtual generic_digest digest() const = 0;
protected:
//*************************************************************************
/// Gets the result as a generic digest.
/// Templated for derived class usage.
//*************************************************************************
template <typename T>
generic_digest get_digest(const T& hash) const
{
const uint8_t* begin = reinterpret_cast<const uint8_t*>(&hash);
return generic_digest(begin, begin + sizeof(hash));
}
private:
etl::endian endianness;
};
}
//*************************************************************************
/// Default streaming operator.
//*************************************************************************
template <typename T>
etl::ihash& operator << (etl::ihash& hash, T value)
{
hash.add(value);
return hash;
}
#endif

View File

@ -54,6 +54,62 @@ namespace etl
public:
class iterator
{
typedef io_port_rw<T, ADDRESS> iop_t;
public:
iterator(iop_t& iop)
: p_iop(&iop)
{
}
iterator(const iterator& other)
: p_iop(other)
{
}
iterator& operator =(const iterator& other)
{
p_iop = other.p_iop;
}
iop_t& operator *()
{
return *p_iop;
}
const iop_t& operator *() const
{
return *p_iop;
}
iterator& operator ++()
{
return *this;
}
iterator operator ++(int)
{
return *this;
}
iterator& operator --()
{
return *this;
}
iterator operator --(int)
{
return *this;
}
private:
iop_t* p_iop;
};
/// Read.
operator T() volatile const
{
@ -78,6 +134,12 @@ namespace etl
{
return reinterpret_cast<pointer_t>(ADDRESS);
}
/// Get the iterator.
iterator get_iterator()
{
return iterator(*this);
}
};
//***************************************************************************

58
ipool.h
View File

@ -35,6 +35,7 @@ SOFTWARE.
#include "pool_base.h"
#include "nullptr.h"
#include "ibitset.h"
#ifndef ETL_THROW_EXCEPTIONS
#include "error_handler.h"
@ -457,7 +458,7 @@ namespace etl
/// \param p_object A pointer to the object to be checked.
/// \return <b>true<\b> if it does, otherwise <b>false</b>
//*************************************************************************
bool is_in_pool(const T* const p_object) const
bool is_in_pool(const T* p_object) const
{
// Does this object belong to this pool?
typename std::iterator_traits<T*>::difference_type distance = p_object - p_buffer;
@ -466,6 +467,61 @@ namespace etl
return ((distance >= 0) && (distance < static_cast<typename std::iterator_traits<T*>::difference_type>(MAX_SIZE)));
}
//*************************************************************************
/// Gets the iterator to the object.
/// If the object is not in the pool then end() is returned.
/// \param object A const reference to the object to be checked.
/// \return An iterator to the object or end().
//*************************************************************************
iterator get_iterator(T& object)
{
if (is_in_pool(object))
{
iterator i_object = begin();
while (i_object != end())
{
// Same one?
if (&object == &*i_object)
{
return i_object;
}
++i_object;
}
}
return end();
}
//*************************************************************************
/// Gets the const_iterator to the object.
/// If the object is not in the pool then end() is returned.
/// \param object A const reference to the object to be checked.
/// \return An const_iterator to the object or end().
//*************************************************************************
const_iterator get_iterator(const T& object) const
{
if (is_in_pool(object))
{
const_iterator i_object = begin();
while (i_object != end())
{
// Same one?
if (&object == &*i_object)
{
return i_object;
}
++i_object;
}
}
return end();
}
protected:
//*************************************************************************

View File

@ -40,10 +40,7 @@ SOFTWARE.
#include "vector_base.h"
#include "type_traits.h"
#include "parameter_type.h"
#ifndef ETL_THROW_EXCEPTIONS
#include "error_handler.h"
#endif
namespace etl
{
@ -193,11 +190,7 @@ namespace etl
{
if (new_size > MAX_SIZE)
{
#ifdef ETL_THROW_EXCEPTIONS
throw vector_full();
#else
error_handler::error(vector_full());
#endif
ETL_ERROR(vector_full());
}
// Size up or size down?
@ -225,17 +218,13 @@ namespace etl
/// If ETL_THROW_EXCEPTIONS is defined and the new size is larger than the
/// maximum then a vector_full is thrown.
///\param new_size The new size.
///\param value The value to fill new elements with. Default = default contructed value.
///\param value The value to fill new elements with. Default = default constructed value.
//*********************************************************************
void resize(size_t new_size, T value)
{
if (new_size > MAX_SIZE)
{
#ifdef ETL_THROW_EXCEPTIONS
throw vector_full();
#else
error_handler::error(vector_full());
#endif
ETL_ERROR(vector_full());
}
// Size up?
@ -286,11 +275,7 @@ namespace etl
{
if (i >= current_size)
{
#ifdef ETL_THROW_EXCEPTIONS
throw vector_out_of_bounds();
#else
error_handler::error(vector_out_of_bounds());
#endif
ETL_ERROR(vector_out_of_bounds());
}
return p_buffer[i];
@ -306,11 +291,7 @@ namespace etl
{
if (i >= current_size)
{
#ifdef ETL_THROW_EXCEPTIONS
throw vector_out_of_bounds();
#else
error_handler::error(vector_out_of_bounds());
#endif
ETL_ERROR(vector_out_of_bounds());
}
return p_buffer[i];
@ -385,20 +366,12 @@ namespace etl
if (count < 0)
{
#ifdef ETL_THROW_EXCEPTIONS
throw vector_iterator();
#else
error_handler::error(vector_iterator());
#endif
ETL_ERROR(vector_iterator());
}
if (static_cast<size_t>(count) > MAX_SIZE)
{
#ifdef ETL_THROW_EXCEPTIONS
throw vector_full();
#else
error_handler::error(vector_full());
#endif
ETL_ERROR( vector_full());
}
#endif
@ -424,11 +397,7 @@ namespace etl
if (n > MAX_SIZE)
{
#ifdef ETL_THROW_EXCEPTIONS
throw vector_full();
#else
error_handler::error(vector_full());
#endif
ETL_ERROR(vector_full());
}
else
{
@ -454,16 +423,10 @@ namespace etl
//*************************************************************************
void push_back()
{
#ifdef ETL_THROW_EXCEPTIONS
if (current_size == MAX_SIZE)
{
throw vector_full();
ETL_ERROR(vector_full());
}
#else
{
error_handler::error(vector_full());
}
#endif
create_element();
}
@ -477,11 +440,7 @@ namespace etl
{
if (current_size == MAX_SIZE)
{
#ifdef ETL_THROW_EXCEPTIONS
throw vector_full();
#else
error_handler::error(vector_full());
#endif
ETL_ERROR(vector_full());
}
else
{
@ -511,11 +470,7 @@ namespace etl
{
if ((current_size + 1) > MAX_SIZE)
{
#ifdef ETL_THROW_EXCEPTIONS
throw vector_full();
#else
error_handler::error(vector_full());
#endif
ETL_ERROR(vector_full());
}
else
{
@ -542,11 +497,7 @@ namespace etl
{
if ((current_size + n) > MAX_SIZE)
{
#ifdef ETL_THROW_EXCEPTIONS
throw vector_full();
#else
error_handler::error(vector_full());
#endif
ETL_ERROR(vector_full());
}
else
{
@ -613,11 +564,7 @@ namespace etl
if ((current_size + count) > MAX_SIZE)
{
#ifdef ETL_THROW_EXCEPTIONS
throw vector_full();
#else
error_handler::error(vector_full());
#endif
ETL_ERROR(vector_full());
}
else
{

177
jenkins.h Normal file
View File

@ -0,0 +1,177 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
Copyright(c) 2014 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef __ETL_JENKINS__
#define __ETL_JENKINS__
#include <stdint.h>
#include <iterator>
#include "static_assert.h"
#include "type_traits.h"
#include "error_handler.h"
#include "ihash.h"
#if defined(COMPILER_KEIL)
#pragma diag_suppress 1300
#endif
///\defgroup jenkins Jenkins 32 & 64 bit hash calculations
///\ingroup maths
namespace etl
{
//***************************************************************************
/// Calculates the jenkins hash.
///\ingroup jenkins
//***************************************************************************
template <typename THash>
class jenkins
{
public:
STATIC_ASSERT((etl::is_same<THash, uint32_t>::value || etl::is_same<THash, uint64_t>::value), "Only 32 & 64 bit types supported");
typedef THash value_type;
//*************************************************************************
/// Default constructor.
//*************************************************************************
jenkins()
{
reset();
}
//*************************************************************************
/// Constructor from range.
/// \param begin Start of the range.
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
jenkins(TIterator begin, const TIterator end)
{
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Incompatible type");
reset();
while (begin != end)
{
hash += *begin++;
hash += (hash << 10);
hash ^= (hash >> 6);
}
}
//*************************************************************************
/// Resets the CRC to the initial state.
//*************************************************************************
void reset()
{
hash = 0;
is_finalised = false;
}
//*************************************************************************
/// Adds a range.
/// \param begin
/// \param end
//*************************************************************************
template<typename TIterator>
void add(TIterator begin, const TIterator end)
{
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Incompatible type");
if (is_finalised)
{
ETL_ERROR(hash_finalised());
}
else
{
while (begin != end)
{
hash += *begin++;
hash += (hash << 10);
hash ^= (hash >> 6);
}
}
}
//*************************************************************************
/// \param value The char to add to the jenkins.
//*************************************************************************
void add(uint8_t value)
{
if (is_finalised)
{
ETL_ERROR(hash_finalised());
}
else
{
hash += value;
hash += (hash << 10);
hash ^= (hash >> 6);
}
}
//*************************************************************************
/// Gets the jenkins value.
//*************************************************************************
value_type value()
{
finalise();
return hash;
}
//*************************************************************************
/// Conversion operator to value_type.
//*************************************************************************
operator value_type ()
{
return value();
}
private:
void finalise()
{
if (!is_finalised)
{
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
is_finalised = true;
}
}
value_type hash;
bool is_finalised;
};
}
#endif

245
murmur3.h Normal file
View File

@ -0,0 +1,245 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
Copyright(c) 2014 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef __ETL_MURMUR3__
#define __ETL_MURMUR3__
#include <stdint.h>
#include "ihash.h"
#include "binary.h"
#include "error_handler.h"
#if defined(COMPILER_KEIL)
#pragma diag_suppress 1300
#endif
///\defgroup murmur3 Murmur3 hash calculations
///\ingroup maths
namespace etl
{
//***************************************************************************
/// Calculates the murmur3 hash.
/// See https://en.wikipedia.org/wiki/MurmurHash for more details.
///\tparam ENDIANNESS The endianness of the calculation for input types larger than uint8_t. Default = endian::little.
///\ingroup murmur3
//***************************************************************************
template <typename THash>
class murmur3
{
public:
STATIC_ASSERT((etl::is_same<THash, uint32_t>::value || etl::is_same<THash, uint64_t>::value), "Only 32 & 64 bit types supported");
typedef THash value_type;
//*************************************************************************
/// Default constructor.
/// \param seed The seed value. Default = 0.
//*************************************************************************
murmur3(value_type seed = 0)
: seed(seed)
{
reset();
}
//*************************************************************************
/// Constructor from range.
/// \param begin Start of the range.
/// \param end End of the range.
/// \param seed The seed value. Default = 0.
//*************************************************************************
template<typename TIterator>
murmur3(TIterator begin, const TIterator end, value_type seed = 0)
: seed(seed)
{
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Incompatible type");
reset();
while (begin != end)
{
block |= (*begin++) << (block_fill_count * 8);
if (++block_fill_count == FULL_BLOCK)
{
add_block();
block_fill_count = 0;
block = 0;
}
++char_count;
}
}
//*************************************************************************
/// Resets the hash to the initial state.
//*************************************************************************
void reset()
{
hash = seed;
char_count = 0;
block = 0;
block_fill_count = 0;
is_finalised = false;
}
//*************************************************************************
/// Adds a range.
/// \param begin
/// \param end
//*************************************************************************
template<typename TIterator>
void add(TIterator begin, const TIterator end)
{
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Incompatible type");
if (is_finalised)
{
ETL_ERROR(hash_finalised());
}
else
{
while (begin != end)
{
block |= (*begin++) << (block_fill_count * 8);
if (++block_fill_count == FULL_BLOCK)
{
add_block();
block_fill_count = 0;
block = 0;
}
++char_count;
}
}
}
//*************************************************************************
/// Adds a uint8_t value.
/// If the hash has already been finalised then a 'hash_finalised' error will be emitted.
/// \param value The char to add to the hash.
//*************************************************************************
void add(uint8_t value)
{
// We can't add to a finalised hash!
if (is_finalised)
{
ETL_ERROR(hash_finalised());
}
else
{
block |= value << (block_fill_count * 8);
if (++block_fill_count == FULL_BLOCK)
{
add_block();
block_fill_count = 0;
block = 0;
}
++char_count;
}
}
//*************************************************************************
/// Gets the hash value.
//*************************************************************************
value_type value()
{
finalise();
return hash;
}
//*************************************************************************
/// Conversion operator to value_type.
//*************************************************************************
operator value_type ()
{
return value();
}
private:
//*************************************************************************
/// Adds a filled block to the hash.
//*************************************************************************
void add_block()
{
block *= CONSTANT1;
block = rotate_left(block, SHIFT1);
block *= CONSTANT2;
hash ^= block;
hash = rotate_left(hash, SHIFT2);
hash = (hash * MULTIPLY) + ADD;
}
//*************************************************************************
/// Finalises the hash.
//*************************************************************************
void finalise()
{
if (!is_finalised)
{
block *= CONSTANT1;
block = rotate_left(block, SHIFT1);
block *= CONSTANT2;
hash ^= block;
hash ^= char_count;
hash ^= (hash >> 16);
hash *= 0x85EBCA6B;
hash ^= (hash >> 13);
hash *= 0xC2B2AE35;
hash ^= (hash >> 16);
is_finalised = true;
}
}
bool is_finalised;
uint8_t block_fill_count;
size_t char_count;
value_type block;
value_type hash;
value_type seed;
static const uint8_t FULL_BLOCK = 4;
static const value_type CONSTANT1 = 0xCC9E2D51;
static const value_type CONSTANT2 = 0x1B873593;
static const value_type SHIFT1 = 15;
static const value_type SHIFT2 = 13;
static const value_type MULTIPLY = 5;
static const value_type ADD = 0xE6546B64;
};
}
#endif

View File

@ -90,6 +90,7 @@ namespace etl
{
}
};
//*****************************************************************************
/// An optional type.
/// If the optional type is not initialised then a type is not constructed.
@ -121,11 +122,11 @@ namespace etl
/// Copy constructor.
//***************************************************************************
optional(const optional& other)
: valid(bool(other))
{
if (other)
if (valid)
{
new (storage.template get_address<T>()) T(other.value());
valid = true;
}
}
@ -192,7 +193,7 @@ namespace etl
//***************************************************************************
/// Assignment operator from value type.
//***************************************************************************
optional& operator =(T& value)
optional& operator =(const T& value)
{
if (valid)
{
@ -337,6 +338,16 @@ namespace etl
return valid ? value() : default_value;
}
//***************************************************************************
/// Swaps this value with another.
//***************************************************************************
void swap(optional& other)
{
optional temp(*this);
*this = other;
other = temp;
}
private:
typename etl::aligned_storage_as<sizeof(T), T>::type storage;
@ -344,6 +355,15 @@ namespace etl
};
}
//*************************************************************************
/// Swaps the values.
//*************************************************************************
template <typename T>
void swap(etl::optional<T>& lhs, etl::optional<T>& rhs)
{
lhs.swap(rhs);
}
//***************************************************************************
/// Equality operator.
//***************************************************************************

57
pearson.cpp Normal file
View File

@ -0,0 +1,57 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
Copyright(c) 2015 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include <stdint.h>
namespace etl
{
//***************************************************************************
/// Pearson lookup table
/// \ingroup pearson
//***************************************************************************
extern const uint8_t PEARSON_LOOKUP[] =
{
228, 39, 61, 95, 227, 187, 0, 197, 31, 189, 161, 222, 34, 15, 221, 246,
19, 234, 6, 50, 113, 3, 91, 63, 77, 245, 144, 2, 183, 196, 25, 226,
97, 126, 48, 59, 217, 4, 100, 145, 12, 88, 203, 149, 80, 154, 38, 27,
224, 218, 158, 115, 202, 79, 53, 83, 242, 36, 139, 131, 136, 191, 42, 170,
23, 99, 156, 51, 143, 60, 233, 206, 62, 108, 17, 67, 81, 71, 93, 195,
26, 231, 247, 96, 24, 200, 176, 209, 152, 212, 138, 165, 75, 185, 130, 248,
125, 110, 10, 116, 201, 90, 69, 204, 85, 251, 78, 157, 47, 184, 169, 141,
134, 230, 89, 21, 146, 46, 55, 128, 148, 207, 216, 11, 114, 199, 103, 102,
166, 244, 5, 104, 225, 160, 132, 28, 172, 65, 121, 140, 153, 119, 198, 210,
58, 87, 117, 177, 33, 22, 13, 37, 49, 174, 109, 40, 73, 211, 18, 167,
164, 252, 168, 74, 30, 173, 35, 98, 66, 193, 94, 175, 86, 54, 179, 122,
220, 151, 192, 29, 133, 254, 155, 127, 240, 232, 190, 180, 8, 68, 236, 20,
137, 92, 219, 208, 52, 250, 147, 142, 111, 112, 120, 45, 135, 255, 123, 229,
57, 182, 243, 124, 186, 253, 7, 237, 9, 16, 70, 171, 235, 107, 223, 118,
215, 178, 194, 181, 43, 188, 106, 105, 64, 241, 84, 238, 159, 44, 32, 76,
213, 163, 150, 101, 129, 14, 249, 205, 214, 1, 41, 56, 162, 72, 239, 82
} ;
}

163
pearson.h Normal file
View File

@ -0,0 +1,163 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
Copyright(c) 2014 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef __ETL_PEARSON__
#define __ETL_PEARSON__
#include <stdint.h>
#include "static_assert.h"
#include "type_traits.h"
#include "endian.h"
#include "ihash.h"
#include "array.h"
#include "container.h"
#if defined(COMPILER_KEIL)
#pragma diag_suppress 1300
#endif
///\defgroup pearson Pearson hash calculation
///\ingroup pearson
namespace etl
{
//***************************************************************************
/// Pearson lookup table
/// \ingroup pearson
//***************************************************************************
extern const uint8_t PEARSON_LOOKUP[];
//***************************************************************************
/// Calculates a Pearson hash
///\tparam HASH_LENGTH The number of elements in the hash.
/// \ingroup pearson
//***************************************************************************
template <const size_t HASH_LENGTH>
class pearson
{
public:
typedef etl::array<uint8_t, HASH_LENGTH> value_type;
//*************************************************************************
/// Default constructor.
//*************************************************************************
pearson()
: first(true)
{
reset();
}
//*************************************************************************
/// Constructor from range.
/// \param begin Start of the range.
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
pearson(TIterator begin, const TIterator end)
: first(true)
{
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
reset();
add(begin, end);
}
//*************************************************************************
/// Resets the hash to the initial state.
//*************************************************************************
void reset()
{
hash.fill(0);
}
//*************************************************************************
/// Adds a range.
/// \param begin
/// \param end
//*************************************************************************
template<typename TIterator>
void add(TIterator begin, const TIterator end)
{
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
while (begin != end)
{
add(*begin++);
}
}
//*************************************************************************
/// \param value The char to add to the hash.
//*************************************************************************
void add(uint8_t value)
{
if (first)
{
for (size_t i = 0; i < HASH_SIZE; ++i)
{
hash[i] = PEARSON_LOOKUP[(uint32_t(value) + i) % 256];
}
first = false;
}
else
{
for (size_t i = 0; i < HASH_SIZE; ++i)
{
hash[i] = PEARSON_LOOKUP[hash[i] ^ value];
}
}
}
//*************************************************************************
/// Gets the hash value.
//*************************************************************************
value_type value() const
{
return hash;
}
//*************************************************************************
/// Conversion operator to value_type.
//*************************************************************************
operator value_type () const
{
return value();
}
private:
bool first;
value_type hash;
};
}
#endif

17
power.h
View File

@ -42,29 +42,30 @@ namespace etl
//***************************************************************************
///\ingroup power
/// Calculates powers.
///\note Only supports positive N.
//***************************************************************************
template <const size_t N, const size_t POWER>
struct power
{
enum value_type
{
value = N * power<N, POWER - 1>::value
};
static const uint64_t value = N * power<N, POWER - 1>::value;
};
//***************************************************************************
/// Calculates powers.
///\note Only supports positive N.
/// Specialisation for POWER == 0.
//***************************************************************************
template <const size_t N>
struct power<N, 0>
{
enum value_type
{
value = 1
};
static const uint64_t value = 1;
};
//***************************************************************************
/// Declaration of static 'value' for power.
//***************************************************************************
template <const size_t N, const size_t POWER> const uint64_t power<N, POWER>::value;
//***************************************************************************
///\ingroup power
/// Calculates the rounded up power of 2.

View File

@ -15,6 +15,7 @@
<Add option="-std=c++11" />
<Add option="-g" />
<Add option="-DUNITTEST_MINGW" />
<Add option="-DPLATFORM_WINDOWS" />
</Compiler>
<ExtraCommands>
<Add after="bin\Debug\ETL.exe" />
@ -29,10 +30,11 @@
<Compiler>
<Add option="-std=c++11" />
<Add option="-g" />
<Add option="-DUNITTEST_MINGW" />
<Add option="-D_DEBUG" />
<Add option="-DPLATFORM_LINUX" />
</Compiler>
<ExtraCommands>
<Add after="bin\Debug\ETL.exe" />
<Add after="bin/Debug/ETL" />
<Mode after="always" />
</ExtraCommands>
</Target>
@ -42,8 +44,8 @@
<Add option="-Wall" />
<Add option="-fexceptions" />
<Add option="-DCOMPILER_GCC" />
<Add option="-DPLATFORM_WINDOWS" />
<Add option="-DETL_THROW_EXCEPTIONS" />
<Add option="-D_DEBUG" />
<Add directory="../../../unittest-cpp" />
</Compiler>
<Unit filename="../../../unittest-cpp/UnitTest++/AssertException.cpp" />
@ -161,6 +163,7 @@
<Unit filename="../../integral_limits.h" />
<Unit filename="../../io_port.h" />
<Unit filename="../../iqueue.h" />
<Unit filename="../../iset.h" />
<Unit filename="../../istack.h" />
<Unit filename="../../ivector.h" />
<Unit filename="../../largest.h" />
@ -180,6 +183,8 @@
<Unit filename="../../power.h" />
<Unit filename="../../queue.h" />
<Unit filename="../../queue_base.h" />
<Unit filename="../../set.h" />
<Unit filename="../../set_base.h" />
<Unit filename="../../smallest.h" />
<Unit filename="../../stack.h" />
<Unit filename="../../stack_base.h" />
@ -226,6 +231,7 @@
<Unit filename="../test_optional.cpp" />
<Unit filename="../test_pool.cpp" />
<Unit filename="../test_queue.cpp" />
<Unit filename="../test_set.cpp" />
<Unit filename="../test_smallest.cpp" />
<Unit filename="../test_stack.cpp" />
<Unit filename="../test_type_traits.cpp" />

File diff suppressed because it is too large Load Diff

View File

@ -1,34 +1,19 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_layout_file>
<ActiveTarget name="Windows" />
<File name="..\..\stack.h" open="1" top="0" tabpos="16" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<ActiveTarget name="Linux" />
<File name="..\..\..\unittest-cpp\UnitTest++\ExecuteTest.h" open="1" top="0" tabpos="8" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="3203" topLine="57" />
<Cursor1 position="1247" topLine="4" />
</Cursor>
</File>
<File name="..\test_map.cpp" open="1" top="0" tabpos="18" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\test_io_port.cpp" open="0" top="0" tabpos="21" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="4433" topLine="84" />
<Cursor1 position="2724" topLine="58" />
</Cursor>
</File>
<File name="..\..\static_assert.h" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\io_port.h" open="1" top="0" tabpos="15" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="1356" topLine="10" />
</Cursor>
</File>
<File name="..\..\optional.h" open="1" top="1" tabpos="22" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="4021" topLine="67" />
</Cursor>
</File>
<File name="..\..\..\unittest-cpp\UnitTest++\Config.h" open="0" top="0" tabpos="4" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="773" topLine="0" />
</Cursor>
</File>
<File name="..\..\function.h" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="3693" topLine="67" />
<Cursor1 position="2314" topLine="48" />
</Cursor>
</File>
<File name="..\..\array.h" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
@ -36,59 +21,34 @@
<Cursor1 position="1998" topLine="258" />
</Cursor>
</File>
<File name="..\..\bitset.h" open="1" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\pool.h" open="0" top="0" tabpos="14" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="4838" topLine="145" />
<Cursor1 position="2334" topLine="35" />
</Cursor>
</File>
<File name="..\..\..\unittest-cpp\UnitTest++\Win32\TimeHelpers.h" open="0" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\integral_limits.h" open="0" top="0" tabpos="6" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="245" topLine="0" />
<Cursor1 position="2272" topLine="36" />
</Cursor>
</File>
<File name="..\test_type_traits.cpp" open="1" top="0" tabpos="9" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\stack.h" open="0" top="0" tabpos="16" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="34843" topLine="428" />
<Cursor1 position="3203" topLine="57" />
</Cursor>
</File>
<File name="..\..\container.h" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\bloom_filter.h" open="1" top="0" tabpos="15" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="2523" topLine="42" />
<Cursor1 position="3055" topLine="57" />
</Cursor>
</File>
<File name="..\..\ilist.h" open="1" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\optional.h" open="0" top="0" tabpos="22" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="17660" topLine="539" />
<Cursor1 position="2746" topLine="58" />
</Cursor>
</File>
<File name="..\..\..\unittest-cpp\UnitTest++\ExecuteTest.h" open="0" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\..\unittest-cpp\UnitTest++\Test.cpp" open="1" top="0" tabpos="9" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="355" topLine="0" />
</Cursor>
</File>
<File name="..\test_bloom_filter.cpp" open="1" top="0" tabpos="15" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="6035" topLine="180" />
</Cursor>
</File>
<File name="..\..\io_port.h" open="1" top="0" tabpos="20" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="7715" topLine="301" />
</Cursor>
</File>
<File name="..\test_cyclic_value.cpp" open="1" top="0" tabpos="4" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="1365" topLine="12" />
</Cursor>
</File>
<File name="..\..\lookup.h" open="1" top="0" tabpos="15" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="3734" topLine="55" />
</Cursor>
</File>
<File name="..\..\deque.h" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="4670" topLine="110" />
<Cursor1 position="662" topLine="0" />
</Cursor>
</File>
<File name="..\..\map.h" open="0" top="0" tabpos="10" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
@ -96,57 +56,62 @@
<Cursor1 position="5955" topLine="137" />
</Cursor>
</File>
<File name="..\..\nullptr.h" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\test_cyclic_value.cpp" open="0" top="0" tabpos="4" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="560" topLine="78" />
<Cursor1 position="1365" topLine="12" />
</Cursor>
</File>
<File name="..\..\observer.h" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\..\unittest-cpp\UnitTest++\Config.h" open="0" top="0" tabpos="4" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="5579" topLine="130" />
<Cursor1 position="773" topLine="0" />
</Cursor>
</File>
<File name="..\..\pool.h" open="1" top="0" tabpos="14" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\test_vector.cpp" open="1" top="0" tabpos="6" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="2334" topLine="35" />
<Cursor1 position="4094" topLine="90" />
</Cursor>
</File>
<File name="..\..\queue.h" open="1" top="0" tabpos="15" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\list.h" open="0" top="0" tabpos="10" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="2984" topLine="48" />
<Cursor1 position="5955" topLine="137" />
</Cursor>
</File>
<File name="..\test_io_port.cpp" open="1" top="0" tabpos="21" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\type_traits.h" open="1" top="0" tabpos="14" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="2724" topLine="58" />
<Cursor1 position="7979" topLine="189" />
</Cursor>
</File>
<File name="..\test_optional.cpp" open="1" top="0" tabpos="23" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\cyclic_value.h" open="0" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="3050" topLine="59" />
<Cursor1 position="3578" topLine="85" />
</Cursor>
</File>
<File name="..\..\type_traits.h" open="1" top="0" tabpos="7" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\ilist.h" open="0" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="5782" topLine="136" />
<Cursor1 position="17660" topLine="539" />
</Cursor>
</File>
<File name="..\..\alignment.h" open="1" top="0" tabpos="25" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\..\unittest-cpp\UnitTest++\TestMacros.h" open="0" top="0" tabpos="13" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="5607" topLine="134" />
<Cursor1 position="1865" topLine="28" />
</Cursor>
</File>
<File name="..\..\ideque.h" open="1" top="0" tabpos="24" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\error_handler.h" open="1" top="0" tabpos="17" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="43136" topLine="1333" />
<Cursor1 position="3450" topLine="55" />
</Cursor>
</File>
<File name="..\test_queue.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\test_integral_limits.cpp" open="0" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="1603" topLine="28" />
<Cursor1 position="1416" topLine="13" />
</Cursor>
</File>
<File name="..\..\binary.h" open="1" top="0" tabpos="17" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\test_bloom_filter.cpp" open="1" top="0" tabpos="15" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="6035" topLine="180" />
</Cursor>
</File>
<File name="..\..\binary.h" open="0" top="0" tabpos="17" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="12327" topLine="338" />
</Cursor>
@ -156,9 +121,34 @@
<Cursor1 position="257" topLine="0" />
</Cursor>
</File>
<File name="..\..\bloom_filter.h" open="1" top="0" tabpos="15" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\function.h" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="3055" topLine="57" />
<Cursor1 position="3693" topLine="67" />
</Cursor>
</File>
<File name="..\test_algorithm.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="1544" topLine="0" />
</Cursor>
</File>
<File name="..\..\..\unittest-cpp\UnitTest++\Posix\SignalTranslator.h" open="1" top="1" tabpos="16" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="271" topLine="0" />
</Cursor>
</File>
<File name="..\test_queue.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="1603" topLine="28" />
</Cursor>
</File>
<File name="..\..\vector_base.h" open="1" top="0" tabpos="7" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="2307" topLine="19" />
</Cursor>
</File>
<File name="..\..\nullptr.h" open="1" top="0" tabpos="15" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="560" topLine="9" />
</Cursor>
</File>
<File name="..\main.cpp" open="0" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
@ -166,74 +156,129 @@
<Cursor1 position="277" topLine="0" />
</Cursor>
</File>
<File name="..\test_optional.cpp" open="0" top="0" tabpos="23" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="3050" topLine="59" />
</Cursor>
</File>
<File name="..\..\observer.h" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="5579" topLine="130" />
</Cursor>
</File>
<File name="..\test_map.cpp" open="1" top="0" tabpos="4" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="4405" topLine="112" />
</Cursor>
</File>
<File name="..\..\queue.h" open="1" top="0" tabpos="13" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="2984" topLine="48" />
</Cursor>
</File>
<File name="..\..\lookup.h" open="1" top="0" tabpos="15" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="3734" topLine="55" />
</Cursor>
</File>
<File name="..\..\ivector.h" open="1" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="14318" topLine="364" />
</Cursor>
</File>
<File name="..\test_bitset.cpp" open="0" top="0" tabpos="19" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="17510" topLine="588" />
</Cursor>
</File>
<File name="..\..\endian.h" open="0" top="0" tabpos="12" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="2235" topLine="37" />
</Cursor>
</File>
<File name="..\..\bitset.h" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="4838" topLine="145" />
</Cursor>
</File>
<File name="..\test_set.cpp" open="1" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="5885" topLine="199" />
</Cursor>
</File>
<File name="..\..\container.h" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="2523" topLine="42" />
</Cursor>
</File>
<File name="..\test_type_traits.cpp" open="0" top="0" tabpos="9" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="34843" topLine="428" />
</Cursor>
</File>
<File name="..\..\static_assert.h" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="1356" topLine="10" />
</Cursor>
</File>
<File name="..\..\Doxyfile" open="0" top="0" tabpos="8" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="56760" topLine="1251" />
</Cursor>
</File>
<File name="..\test_deque.cpp" open="1" top="0" tabpos="12" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="21475" topLine="641" />
</Cursor>
</File>
<File name="..\test_array.cpp" open="0" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="2123" topLine="55" />
</Cursor>
</File>
<File name="..\..\imap.h" open="1" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\deque.h" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="60526" topLine="1694" />
<Cursor1 position="4670" topLine="110" />
</Cursor>
</File>
<File name="..\test_bitset.cpp" open="1" top="0" tabpos="19" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\ideque.h" open="0" top="0" tabpos="24" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="17510" topLine="588" />
<Cursor1 position="43136" topLine="1333" />
</Cursor>
</File>
<File name="..\..\Doxyfile" open="1" top="0" tabpos="8" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\..\unittest-cpp\UnitTest++\TestRunner.cpp" open="1" top="0" tabpos="10" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="56760" topLine="1251" />
<Cursor1 position="2020" topLine="29" />
</Cursor>
</File>
<File name="..\..\integral_limits.h" open="1" top="0" tabpos="6" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\imap.h" open="1" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="2272" topLine="36" />
<Cursor1 position="65581" topLine="1823" />
</Cursor>
</File>
<File name="..\..\..\unittest-cpp\UnitTest++\Posix\SignalTranslator.h" open="1" top="0" tabpos="10" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\..\unittest-cpp\UnitTest++\TestRunner.h" open="1" top="0" tabpos="11" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="616" topLine="0" />
<Cursor1 position="692" topLine="0" />
</Cursor>
</File>
<File name="..\test_deque.cpp" open="1" top="0" tabpos="15" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\..\unittest-cpp\UnitTest++\Win32\TimeHelpers.h" open="0" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="21475" topLine="641" />
<Cursor1 position="245" topLine="0" />
</Cursor>
</File>
<File name="..\..\list.h" open="0" top="0" tabpos="10" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\alignment.h" open="0" top="0" tabpos="25" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="5955" topLine="137" />
<Cursor1 position="5607" topLine="134" />
</Cursor>
</File>
<File name="..\..\..\unittest-cpp\UnitTest++\Test.cpp" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\iset.h" open="1" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="200" topLine="0" />
<Cursor1 position="1386" topLine="9" />
</Cursor>
</File>
<File name="..\..\cyclic_value.h" open="1" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="3578" topLine="85" />
</Cursor>
</File>
<File name="..\..\endian.h" open="1" top="0" tabpos="12" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="2235" topLine="37" />
</Cursor>
</File>
<File name="..\..\..\unittest-cpp\UnitTest++\TestMacros.h" open="1" top="0" tabpos="13" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="1865" topLine="28" />
</Cursor>
</File>
<File name="..\test_hash.cpp" open="1" top="0" tabpos="11" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\test_hash.cpp" open="0" top="0" tabpos="11" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="4733" topLine="114" />
</Cursor>
</File>
<File name="..\test_integral_limits.cpp" open="1" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="1416" topLine="13" />
</Cursor>
</File>
</CodeBlocks_layout_file>

View File

@ -39,6 +39,7 @@ class TestDataDC
public:
TestDataDC()
: value(T())
{
}
@ -82,6 +83,10 @@ class TestDataNDC
{
public:
TestDataNDC()
: value(T())
{}
TestDataNDC(const T& value)
: value(value)
{}

332
test/murmurhash3.cpp Normal file
View File

@ -0,0 +1,332 @@
//-----------------------------------------------------------------------------
// MurmurHash3 was written by Austin Appleby, and is placed in the public
// domain. The author hereby disclaims copyright to this source code.
// Note - The x86 and x64 versions do _not_ produce the same results, as the
// algorithms are optimized for their respective platforms. You can still
// compile and run any of them on any platform, but your performance with the
// non-native version will be less than optimal.
#include "MurmurHash3.h"
//-----------------------------------------------------------------------------
// Platform-specific functions and macros
// Microsoft Visual Studio
#if defined(_MSC_VER)
#define FORCE_INLINE __forceinline
#include <stdlib.h>
#define ROTL32(x,y) _rotl(x,y)
#define ROTL64(x,y) _rotl64(x,y)
#define BIG_CONSTANT(x) (x)
// Other compilers
#else // defined(_MSC_VER)
#define FORCE_INLINE inline __attribute__((always_inline))
inline uint32_t rotl32(uint32_t x, int8_t r)
{
return (x << r) | (x >> (32 - r));
}
inline uint64_t rotl64(uint64_t x, int8_t r)
{
return (x << r) | (x >> (64 - r));
}
#define ROTL32(x,y) rotl32(x,y)
#define ROTL64(x,y) rotl64(x,y)
#define BIG_CONSTANT(x) (x##LLU)
#endif // !defined(_MSC_VER)
//-----------------------------------------------------------------------------
// Block read - if your platform needs to do endian-swapping or can only
// handle aligned reads, do the conversion here
FORCE_INLINE uint32_t getblock32(const uint32_t * p, int i)
{
return p[i];
}
FORCE_INLINE uint64_t getblock64(const uint64_t * p, int i)
{
return p[i];
}
//-----------------------------------------------------------------------------
// Finalization mix - force all bits of a hash block to avalanche
FORCE_INLINE uint32_t fmix32(uint32_t h)
{
h ^= h >> 16;
h *= 0x85ebca6b;
h ^= h >> 13;
h *= 0xc2b2ae35;
h ^= h >> 16;
return h;
}
//----------
FORCE_INLINE uint64_t fmix64(uint64_t k)
{
k ^= k >> 33;
k *= BIG_CONSTANT(0xff51afd7ed558ccd);
k ^= k >> 33;
k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53);
k ^= k >> 33;
return k;
}
//-----------------------------------------------------------------------------
void MurmurHash3_x86_32(const void * key, int len, uint32_t seed, void * out)
{
const uint8_t * data = (const uint8_t*)key;
const int nblocks = len / 4;
uint32_t h1 = seed;
const uint32_t c1 = 0xcc9e2d51;
const uint32_t c2 = 0x1b873593;
//----------
// body
const uint32_t * blocks = (const uint32_t *)(data + nblocks * 4);
for (int i = -nblocks; i; i++)
{
uint32_t k1 = getblock32(blocks, i);
k1 *= c1;
k1 = ROTL32(k1, 15);
k1 *= c2;
h1 ^= k1;
h1 = ROTL32(h1, 13);
h1 = h1 * 5 + 0xe6546b64;
}
//----------
// tail
const uint8_t * tail = (const uint8_t*)(data + nblocks * 4);
uint32_t k1 = 0;
switch (len & 3)
{
case 3: k1 ^= tail[2] << 16;
case 2: k1 ^= tail[1] << 8;
case 1: k1 ^= tail[0];
k1 *= c1; k1 = ROTL32(k1, 15); k1 *= c2; h1 ^= k1;
};
//----------
// finalization
h1 ^= len;
h1 = fmix32(h1);
*(uint32_t*)out = h1;
}
//-----------------------------------------------------------------------------
void MurmurHash3_x86_128(const void * key, const int len,
uint32_t seed, void * out)
{
const uint8_t * data = (const uint8_t*)key;
const int nblocks = len / 16;
uint32_t h1 = seed;
uint32_t h2 = seed;
uint32_t h3 = seed;
uint32_t h4 = seed;
const uint32_t c1 = 0x239b961b;
const uint32_t c2 = 0xab0e9789;
const uint32_t c3 = 0x38b34ae5;
const uint32_t c4 = 0xa1e38b93;
//----------
// body
const uint32_t * blocks = (const uint32_t *)(data + nblocks * 16);
for (int i = -nblocks; i; i++)
{
uint32_t k1 = getblock32(blocks, i * 4 + 0);
uint32_t k2 = getblock32(blocks, i * 4 + 1);
uint32_t k3 = getblock32(blocks, i * 4 + 2);
uint32_t k4 = getblock32(blocks, i * 4 + 3);
k1 *= c1; k1 = ROTL32(k1, 15); k1 *= c2; h1 ^= k1;
h1 = ROTL32(h1, 19); h1 += h2; h1 = h1 * 5 + 0x561ccd1b;
k2 *= c2; k2 = ROTL32(k2, 16); k2 *= c3; h2 ^= k2;
h2 = ROTL32(h2, 17); h2 += h3; h2 = h2 * 5 + 0x0bcaa747;
k3 *= c3; k3 = ROTL32(k3, 17); k3 *= c4; h3 ^= k3;
h3 = ROTL32(h3, 15); h3 += h4; h3 = h3 * 5 + 0x96cd1c35;
k4 *= c4; k4 = ROTL32(k4, 18); k4 *= c1; h4 ^= k4;
h4 = ROTL32(h4, 13); h4 += h1; h4 = h4 * 5 + 0x32ac3b17;
}
//----------
// tail
const uint8_t * tail = (const uint8_t*)(data + nblocks * 16);
uint32_t k1 = 0;
uint32_t k2 = 0;
uint32_t k3 = 0;
uint32_t k4 = 0;
switch (len & 15)
{
case 15: k4 ^= tail[14] << 16;
case 14: k4 ^= tail[13] << 8;
case 13: k4 ^= tail[12] << 0;
k4 *= c4; k4 = ROTL32(k4, 18); k4 *= c1; h4 ^= k4;
case 12: k3 ^= tail[11] << 24;
case 11: k3 ^= tail[10] << 16;
case 10: k3 ^= tail[9] << 8;
case 9: k3 ^= tail[8] << 0;
k3 *= c3; k3 = ROTL32(k3, 17); k3 *= c4; h3 ^= k3;
case 8: k2 ^= tail[7] << 24;
case 7: k2 ^= tail[6] << 16;
case 6: k2 ^= tail[5] << 8;
case 5: k2 ^= tail[4] << 0;
k2 *= c2; k2 = ROTL32(k2, 16); k2 *= c3; h2 ^= k2;
case 4: k1 ^= tail[3] << 24;
case 3: k1 ^= tail[2] << 16;
case 2: k1 ^= tail[1] << 8;
case 1: k1 ^= tail[0] << 0;
k1 *= c1; k1 = ROTL32(k1, 15); k1 *= c2; h1 ^= k1;
};
//----------
// finalization
h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len;
h1 += h2; h1 += h3; h1 += h4;
h2 += h1; h3 += h1; h4 += h1;
h1 = fmix32(h1);
h2 = fmix32(h2);
h3 = fmix32(h3);
h4 = fmix32(h4);
h1 += h2; h1 += h3; h1 += h4;
h2 += h1; h3 += h1; h4 += h1;
((uint32_t*)out)[0] = h1;
((uint32_t*)out)[1] = h2;
((uint32_t*)out)[2] = h3;
((uint32_t*)out)[3] = h4;
}
//-----------------------------------------------------------------------------
void MurmurHash3_x64_128(const void * key, const int len,
const uint32_t seed, void * out)
{
const uint8_t * data = (const uint8_t*)key;
const int nblocks = len / 16;
uint64_t h1 = seed;
uint64_t h2 = seed;
const uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5);
const uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f);
//----------
// body
const uint64_t * blocks = (const uint64_t *)(data);
for (int i = 0; i < nblocks; i++)
{
uint64_t k1 = getblock64(blocks, i * 2 + 0);
uint64_t k2 = getblock64(blocks, i * 2 + 1);
k1 *= c1; k1 = ROTL64(k1, 31); k1 *= c2; h1 ^= k1;
h1 = ROTL64(h1, 27); h1 += h2; h1 = h1 * 5 + 0x52dce729;
k2 *= c2; k2 = ROTL64(k2, 33); k2 *= c1; h2 ^= k2;
h2 = ROTL64(h2, 31); h2 += h1; h2 = h2 * 5 + 0x38495ab5;
}
//----------
// tail
const uint8_t * tail = (const uint8_t*)(data + nblocks * 16);
uint64_t k1 = 0;
uint64_t k2 = 0;
switch (len & 15)
{
case 15: k2 ^= ((uint64_t)tail[14]) << 48;
case 14: k2 ^= ((uint64_t)tail[13]) << 40;
case 13: k2 ^= ((uint64_t)tail[12]) << 32;
case 12: k2 ^= ((uint64_t)tail[11]) << 24;
case 11: k2 ^= ((uint64_t)tail[10]) << 16;
case 10: k2 ^= ((uint64_t)tail[9]) << 8;
case 9: k2 ^= ((uint64_t)tail[8]) << 0;
k2 *= c2; k2 = ROTL64(k2, 33); k2 *= c1; h2 ^= k2;
case 8: k1 ^= ((uint64_t)tail[7]) << 56;
case 7: k1 ^= ((uint64_t)tail[6]) << 48;
case 6: k1 ^= ((uint64_t)tail[5]) << 40;
case 5: k1 ^= ((uint64_t)tail[4]) << 32;
case 4: k1 ^= ((uint64_t)tail[3]) << 24;
case 3: k1 ^= ((uint64_t)tail[2]) << 16;
case 2: k1 ^= ((uint64_t)tail[1]) << 8;
case 1: k1 ^= ((uint64_t)tail[0]) << 0;
k1 *= c1; k1 = ROTL64(k1, 31); k1 *= c2; h1 ^= k1;
};
//----------
// finalization
h1 ^= len; h2 ^= len;
h1 += h2;
h2 += h1;
h1 = fmix64(h1);
h2 = fmix64(h2);
h1 += h2;
h2 += h1;
((uint64_t*)out)[0] = h1;
((uint64_t*)out)[1] = h2;
}

38
test/murmurhash3.h Normal file
View File

@ -0,0 +1,38 @@
//-----------------------------------------------------------------------------
// MurmurHash3 was written by Austin Appleby, and is placed in the public
// domain. The author hereby disclaims copyright to this source code.
#ifndef _MURMURHASH3_H_
#define _MURMURHASH3_H_
//-----------------------------------------------------------------------------
// Platform-specific functions and macros
// Microsoft Visual Studio
#if defined(_MSC_VER) && (_MSC_VER < 1600)
typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
typedef unsigned __int64 uint64_t;
// Other compilers
#else // defined(_MSC_VER)
#include <stdint.h>
#endif // !defined(_MSC_VER)
//-----------------------------------------------------------------------------
void MurmurHash3_x86_32(const void * key, int len, uint32_t seed, void * out);
void MurmurHash3_x86_128(const void * key, int len, uint32_t seed, void * out);
void MurmurHash3_x64_128(const void * key, int len, uint32_t seed, void * out);
//-----------------------------------------------------------------------------
#endif // _MURMURHASH3_H_

View File

@ -28,6 +28,7 @@ SOFTWARE.
#include <UnitTest++/UnitTest++.h>
#include <cstdint>
#include <type_traits>
#include "../binary.h"
#include "../bitset.h"
@ -62,6 +63,39 @@ size_t test_parity(T value)
return count & 1;
}
// Power of 2.
uint64_t test_power_of_2(int power)
{
uint64_t result = 1;
for (int i = 0; i < power; ++i)
{
result *= 2;
}
return result;
}
// Fold bits.
template <typename TReturn>
TReturn test_fold_bits(uint64_t value, int size)
{
int bits_remaining = 64;
uint64_t mask = test_power_of_2(size) - 1;
TReturn result = 0;
while (bits_remaining > size)
{
result = result ^ (value & mask);
value = value >> size;
bits_remaining -= size;
}
result = result ^ (value & mask);
return result;
}
namespace
{
SUITE(test_binary)
@ -527,7 +561,7 @@ namespace
//*************************************************************************
TEST(test_binary_to_gray32)
{
etl::fnv_1a_32<> hash;
etl::fnv_1a_32 hash;
hash.add(1);
@ -551,7 +585,7 @@ namespace
//*************************************************************************
TEST(test_binary_to_gray64)
{
etl::fnv_1a_64<> hash;
etl::fnv_1a_64 hash;
hash.add(1);
@ -593,7 +627,7 @@ namespace
//*************************************************************************
TEST(test_count_bits_32)
{
etl::fnv_1a_32<> hash;
etl::fnv_1a_32 hash;
for (size_t i = 0; i < 1000000; ++i)
{
@ -608,7 +642,7 @@ namespace
//*************************************************************************
TEST(test_count_bits_64)
{
etl::fnv_1a_64<> hash;
etl::fnv_1a_64 hash;
for (size_t i = 0; i < 1000000; ++i)
{
@ -641,7 +675,7 @@ namespace
//*************************************************************************
TEST(test_parity_32)
{
etl::fnv_1a_32<> hash;
etl::fnv_1a_32 hash;
for (size_t i = 0; i < 1000000; ++i)
{
@ -656,7 +690,7 @@ namespace
//*************************************************************************
TEST(test_parity_64)
{
etl::fnv_1a_64<> hash;
etl::fnv_1a_64 hash;
for (size_t i = 0; i < 1000000; ++i)
{
@ -667,5 +701,216 @@ namespace
CHECK_EQUAL(test_parity(value), etl::parity(value));
}
}
//*************************************************************************
TEST(test_fold_bits)
{
const uint64_t data = 0xE8C9AACCBC3D9A8F;
uint8_t result = etl::fold_bits<uint8_t, 8>(data);
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 1), (etl::fold_bits<uint64_t, 1>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 2), (etl::fold_bits<uint64_t, 2>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 3), (etl::fold_bits<uint64_t, 3>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 4), (etl::fold_bits<uint64_t, 4>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 5), (etl::fold_bits<uint64_t, 5>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 6), (etl::fold_bits<uint64_t, 6>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 7), (etl::fold_bits<uint64_t, 7>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 8), (etl::fold_bits<uint64_t, 8>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 9), (etl::fold_bits<uint64_t, 9>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 10), (etl::fold_bits<uint64_t, 10>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 11), (etl::fold_bits<uint64_t, 11>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 12), (etl::fold_bits<uint64_t, 12>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 13), (etl::fold_bits<uint64_t, 13>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 14), (etl::fold_bits<uint64_t, 14>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 15), (etl::fold_bits<uint64_t, 15>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 16), (etl::fold_bits<uint64_t, 16>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 17), (etl::fold_bits<uint64_t, 17>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 18), (etl::fold_bits<uint64_t, 18>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 19), (etl::fold_bits<uint64_t, 19>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 20), (etl::fold_bits<uint64_t, 20>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 21), (etl::fold_bits<uint64_t, 21>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 22), (etl::fold_bits<uint64_t, 22>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 23), (etl::fold_bits<uint64_t, 23>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 24), (etl::fold_bits<uint64_t, 24>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 25), (etl::fold_bits<uint64_t, 25>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 26), (etl::fold_bits<uint64_t, 26>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 27), (etl::fold_bits<uint64_t, 27>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 28), (etl::fold_bits<uint64_t, 28>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 29), (etl::fold_bits<uint64_t, 29>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 30), (etl::fold_bits<uint64_t, 30>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 31), (etl::fold_bits<uint64_t, 31>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 32), (etl::fold_bits<uint64_t, 32>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 33), (etl::fold_bits<uint64_t, 33>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 34), (etl::fold_bits<uint64_t, 34>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 35), (etl::fold_bits<uint64_t, 35>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 36), (etl::fold_bits<uint64_t, 36>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 37), (etl::fold_bits<uint64_t, 37>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 38), (etl::fold_bits<uint64_t, 38>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 39), (etl::fold_bits<uint64_t, 39>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 40), (etl::fold_bits<uint64_t, 40>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 41), (etl::fold_bits<uint64_t, 41>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 42), (etl::fold_bits<uint64_t, 42>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 43), (etl::fold_bits<uint64_t, 43>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 44), (etl::fold_bits<uint64_t, 44>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 45), (etl::fold_bits<uint64_t, 45>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 46), (etl::fold_bits<uint64_t, 46>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 47), (etl::fold_bits<uint64_t, 47>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 48), (etl::fold_bits<uint64_t, 48>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 49), (etl::fold_bits<uint64_t, 49>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 50), (etl::fold_bits<uint64_t, 50>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 51), (etl::fold_bits<uint64_t, 51>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 52), (etl::fold_bits<uint64_t, 52>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 53), (etl::fold_bits<uint64_t, 53>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 54), (etl::fold_bits<uint64_t, 54>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 55), (etl::fold_bits<uint64_t, 55>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 56), (etl::fold_bits<uint64_t, 56>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 57), (etl::fold_bits<uint64_t, 57>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 58), (etl::fold_bits<uint64_t, 58>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 59), (etl::fold_bits<uint64_t, 59>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 60), (etl::fold_bits<uint64_t, 60>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 61), (etl::fold_bits<uint64_t, 61>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 62), (etl::fold_bits<uint64_t, 62>(data)));
CHECK_EQUAL(test_fold_bits<uint64_t>(data, 63), (etl::fold_bits<uint64_t, 63>(data)));
}
//*************************************************************************
TEST(test_max_value_for_bits)
{
// Check that the values are correct.
CHECK_EQUAL(0, etl::max_value_for_nbits<0>::value);
CHECK_EQUAL(1, etl::max_value_for_nbits<1>::value);
CHECK_EQUAL(3, etl::max_value_for_nbits<2>::value);
CHECK_EQUAL(7, etl::max_value_for_nbits<3>::value);
CHECK_EQUAL(15, etl::max_value_for_nbits<4>::value);
CHECK_EQUAL(31, etl::max_value_for_nbits<5>::value);
CHECK_EQUAL(63, etl::max_value_for_nbits<6>::value);
CHECK_EQUAL(127, etl::max_value_for_nbits<7>::value);
CHECK_EQUAL(255, etl::max_value_for_nbits<8>::value);
CHECK_EQUAL(511, etl::max_value_for_nbits<9>::value);
CHECK_EQUAL(1023, etl::max_value_for_nbits<10>::value);
CHECK_EQUAL(2047, etl::max_value_for_nbits<11>::value);
CHECK_EQUAL(4095, etl::max_value_for_nbits<12>::value);
CHECK_EQUAL(8191, etl::max_value_for_nbits<13>::value);
CHECK_EQUAL(16383, etl::max_value_for_nbits<14>::value);
CHECK_EQUAL(32767, etl::max_value_for_nbits<15>::value);
CHECK_EQUAL(65535, etl::max_value_for_nbits<16>::value);
CHECK_EQUAL(131071, etl::max_value_for_nbits<17>::value);
CHECK_EQUAL(262143, etl::max_value_for_nbits<18>::value);
CHECK_EQUAL(524287, etl::max_value_for_nbits<19>::value);
CHECK_EQUAL(1048575, etl::max_value_for_nbits<20>::value);
CHECK_EQUAL(2097151, etl::max_value_for_nbits<21>::value);
CHECK_EQUAL(4194303, etl::max_value_for_nbits<22>::value);
CHECK_EQUAL(8388607, etl::max_value_for_nbits<23>::value);
CHECK_EQUAL(16777215, etl::max_value_for_nbits<24>::value);
CHECK_EQUAL(33554431, etl::max_value_for_nbits<25>::value);
CHECK_EQUAL(67108863, etl::max_value_for_nbits<26>::value);
CHECK_EQUAL(134217727, etl::max_value_for_nbits<27>::value);
CHECK_EQUAL(268435455, etl::max_value_for_nbits<28>::value);
CHECK_EQUAL(536870911, etl::max_value_for_nbits<29>::value);
CHECK_EQUAL(1073741823, etl::max_value_for_nbits<30>::value);
CHECK_EQUAL(2147483647, etl::max_value_for_nbits<31>::value);
CHECK_EQUAL(4294967295, etl::max_value_for_nbits<32>::value);
CHECK_EQUAL(8589934591, etl::max_value_for_nbits<33>::value);
CHECK_EQUAL(17179869183, etl::max_value_for_nbits<34>::value);
CHECK_EQUAL(34359738367, etl::max_value_for_nbits<35>::value);
CHECK_EQUAL(68719476735, etl::max_value_for_nbits<36>::value);
CHECK_EQUAL(137438953471, etl::max_value_for_nbits<37>::value);
CHECK_EQUAL(274877906943, etl::max_value_for_nbits<38>::value);
CHECK_EQUAL(549755813887, etl::max_value_for_nbits<39>::value);
CHECK_EQUAL(1099511627775, etl::max_value_for_nbits<40>::value);
CHECK_EQUAL(2199023255551, etl::max_value_for_nbits<41>::value);
CHECK_EQUAL(4398046511103, etl::max_value_for_nbits<42>::value);
CHECK_EQUAL(8796093022207, etl::max_value_for_nbits<43>::value);
CHECK_EQUAL(17592186044415, etl::max_value_for_nbits<44>::value);
CHECK_EQUAL(35184372088831, etl::max_value_for_nbits<45>::value);
CHECK_EQUAL(70368744177663, etl::max_value_for_nbits<46>::value);
CHECK_EQUAL(140737488355327, etl::max_value_for_nbits<47>::value);
CHECK_EQUAL(281474976710655, etl::max_value_for_nbits<48>::value);
CHECK_EQUAL(562949953421311, etl::max_value_for_nbits<49>::value);
CHECK_EQUAL(1125899906842623, etl::max_value_for_nbits<50>::value);
CHECK_EQUAL(2251799813685247, etl::max_value_for_nbits<51>::value);
CHECK_EQUAL(4503599627370495, etl::max_value_for_nbits<52>::value);
CHECK_EQUAL(9007199254740991, etl::max_value_for_nbits<53>::value);
CHECK_EQUAL(18014398509481983, etl::max_value_for_nbits<54>::value);
CHECK_EQUAL(36028797018963967, etl::max_value_for_nbits<55>::value);
CHECK_EQUAL(72057594037927935, etl::max_value_for_nbits<56>::value);
CHECK_EQUAL(144115188075855871, etl::max_value_for_nbits<57>::value);
CHECK_EQUAL(288230376151711743, etl::max_value_for_nbits<58>::value);
CHECK_EQUAL(576460752303423487, etl::max_value_for_nbits<59>::value);
CHECK_EQUAL(1152921504606846975, etl::max_value_for_nbits<60>::value);
CHECK_EQUAL(2305843009213693951, etl::max_value_for_nbits<61>::value);
CHECK_EQUAL(4611686018427387903, etl::max_value_for_nbits<62>::value);
CHECK_EQUAL(9223372036854775807, etl::max_value_for_nbits<63>::value);
CHECK_EQUAL(18446744073709551615, etl::max_value_for_nbits<64>::value);
// Check that the value types are correct.
CHECK((std::is_same<uint8_t, etl::max_value_for_nbits<0>::value_type>::value));
CHECK((std::is_same<uint8_t, etl::max_value_for_nbits<1>::value_type>::value));
CHECK((std::is_same<uint8_t, etl::max_value_for_nbits<2>::value_type>::value));
CHECK((std::is_same<uint8_t, etl::max_value_for_nbits<3>::value_type>::value));
CHECK((std::is_same<uint8_t, etl::max_value_for_nbits<4>::value_type>::value));
CHECK((std::is_same<uint8_t, etl::max_value_for_nbits<5>::value_type>::value));
CHECK((std::is_same<uint8_t, etl::max_value_for_nbits<6>::value_type>::value));
CHECK((std::is_same<uint8_t, etl::max_value_for_nbits<7>::value_type>::value));
CHECK((std::is_same<uint8_t, etl::max_value_for_nbits<8>::value_type>::value));
CHECK((std::is_same<uint16_t, etl::max_value_for_nbits<9>::value_type>::value));
CHECK((std::is_same<uint16_t, etl::max_value_for_nbits<10>::value_type>::value));
CHECK((std::is_same<uint16_t, etl::max_value_for_nbits<11>::value_type>::value));
CHECK((std::is_same<uint16_t, etl::max_value_for_nbits<12>::value_type>::value));
CHECK((std::is_same<uint16_t, etl::max_value_for_nbits<13>::value_type>::value));
CHECK((std::is_same<uint16_t, etl::max_value_for_nbits<14>::value_type>::value));
CHECK((std::is_same<uint16_t, etl::max_value_for_nbits<15>::value_type>::value));
CHECK((std::is_same<uint16_t, etl::max_value_for_nbits<16>::value_type>::value));
CHECK((std::is_same<uint32_t, etl::max_value_for_nbits<17>::value_type>::value));
CHECK((std::is_same<uint32_t, etl::max_value_for_nbits<18>::value_type>::value));
CHECK((std::is_same<uint32_t, etl::max_value_for_nbits<19>::value_type>::value));
CHECK((std::is_same<uint32_t, etl::max_value_for_nbits<20>::value_type>::value));
CHECK((std::is_same<uint32_t, etl::max_value_for_nbits<21>::value_type>::value));
CHECK((std::is_same<uint32_t, etl::max_value_for_nbits<22>::value_type>::value));
CHECK((std::is_same<uint32_t, etl::max_value_for_nbits<23>::value_type>::value));
CHECK((std::is_same<uint32_t, etl::max_value_for_nbits<24>::value_type>::value));
CHECK((std::is_same<uint32_t, etl::max_value_for_nbits<25>::value_type>::value));
CHECK((std::is_same<uint32_t, etl::max_value_for_nbits<26>::value_type>::value));
CHECK((std::is_same<uint32_t, etl::max_value_for_nbits<27>::value_type>::value));
CHECK((std::is_same<uint32_t, etl::max_value_for_nbits<28>::value_type>::value));
CHECK((std::is_same<uint32_t, etl::max_value_for_nbits<29>::value_type>::value));
CHECK((std::is_same<uint32_t, etl::max_value_for_nbits<30>::value_type>::value));
CHECK((std::is_same<uint32_t, etl::max_value_for_nbits<31>::value_type>::value));
CHECK((std::is_same<uint32_t, etl::max_value_for_nbits<32>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<33>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<34>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<35>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<36>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<37>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<38>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<39>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<40>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<41>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<42>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<43>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<44>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<45>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<46>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<47>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<48>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<49>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<50>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<51>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<52>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<53>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<54>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<55>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<56>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<57>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<58>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<59>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<60>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<61>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<62>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<63>::value_type>::value));
CHECK((std::is_same<uint64_t, etl::max_value_for_nbits<64>::value_type>::value));
}
};
}

View File

@ -43,7 +43,7 @@ struct hash1_t
size_t operator ()(argument_type text) const
{
return etl::fnv_1a_32<>(text, text + strlen(text));
return etl::fnv_1a_32(text, text + strlen(text));
}
};
@ -53,7 +53,7 @@ struct hash2_t
size_t operator ()(argument_type text) const
{
return etl::crc32<>(text, text + strlen(text));
return etl::crc32(text, text + strlen(text));
}
};
@ -63,7 +63,7 @@ struct hash3_t
size_t operator ()(argument_type text) const
{
return etl::crc16<>(text, text + strlen(text)) | (etl::crc16_ccitt<>(text, text + strlen(text)) << 16);
return etl::crc16(text, text + strlen(text)) | (etl::crc16_ccitt(text, text + strlen(text)) << 16);
}
};

154
test/test_bsd_checksum.cpp Normal file
View File

@ -0,0 +1,154 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
Copyright(c) 2014 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include <UnitTest++/UnitTest++.h>
#include <iterator>
#include <string>
#include <vector>
#include <stdint.h>
#include "../bsd_checksum.h"
#include "../endian.h"
template <typename TSum, typename TIterator>
TSum reference_checksum(TIterator begin, TIterator end)
{
typedef typename std::iterator_traits<TIterator>::value_type value_type;
TSum checksum = 0;
while (begin != end)
{
value_type value = *begin++;
for (int i = 0; i < sizeof(value_type); ++i)
{
uint8_t byte = (value >> (i * 8)) & 0xFF;
checksum = etl::rotate_right(checksum) + byte;
}
}
return checksum;
}
namespace
{
SUITE(test_checksum)
{
//*************************************************************************
TEST(test_checksum_constructor)
{
std::string data("123456789");
uint8_t sum = etl::bsd_checksum<uint8_t>(data.begin(), data.end());
uint8_t compare = reference_checksum<uint8_t>(data.begin(), data.end());
CHECK_EQUAL(int(compare), int(sum));
}
//*************************************************************************
TEST(test_checksum_add_values8_add)
{
std::string data("123456789");
etl::bsd_checksum<uint8_t> checksum_calculator;
for (size_t i = 0; i < data.size(); ++i)
{
checksum_calculator.add(data[i]);
}
uint8_t sum = checksum_calculator;
uint8_t compare = reference_checksum<uint8_t>(data.begin(), data.end());
CHECK_EQUAL(int(compare), int(sum));
}
//*************************************************************************
TEST(test_checksum_add_values8_operator_plus_equals)
{
std::string data("123456789");
etl::bsd_checksum<uint8_t> checksum_calculator;
for (size_t i = 0; i < data.size(); ++i)
{
checksum_calculator.add(data[i]);
}
uint8_t sum = checksum_calculator;
uint8_t compare = reference_checksum<uint8_t>(data.begin(), data.end());
CHECK_EQUAL(int(compare), int(sum));
}
//*************************************************************************
TEST(test_checksum_add_range)
{
std::string data("123456789");
etl::bsd_checksum<uint8_t> checksum_calculator;
checksum_calculator.add(data.begin(), data.end());
uint8_t sum = checksum_calculator.value();
uint8_t compare = reference_checksum<uint8_t>(data.begin(), data.end());
CHECK_EQUAL(int(compare), int(sum));
}
//*************************************************************************
TEST(test_checksum_add_range_sum32)
{
std::string data("1");
etl::bsd_checksum<uint32_t> checksum_calculator;
checksum_calculator.add(data.begin(), data.end());
uint32_t sum = checksum_calculator.value();
uint32_t compare = reference_checksum<uint32_t>(data.begin(), data.end());
CHECK_EQUAL(compare, sum);
}
//*************************************************************************
TEST(test_checksum_add_range_endian)
{
std::vector<uint8_t> data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
std::vector<uint32_t> data2 = { 0x04030201, 0x08070605 };
std::vector<uint8_t> data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };
uint64_t hash1 = etl::bsd_checksum<uint8_t>(data1.begin(), data1.end());
uint64_t hash2 = etl::bsd_checksum<uint8_t>((uint8_t*)&data2[0], (uint8_t*)&data2[0] + (data2.size() * sizeof(uint32_t)));
uint64_t hash3 = etl::bsd_checksum<uint8_t>(data3.rbegin(), data3.rend());
CHECK_EQUAL(hash1, hash2);
CHECK_EQUAL(hash1, hash3);
}
};
}

View File

@ -73,82 +73,14 @@ namespace
etl::checksum<uint8_t> checksum_calculator;
for (size_t i = 0; i < data.size(); ++i)
{
checksum_calculator += data[i];
}
uint8_t sum = checksum_calculator;
CHECK_EQUAL(221, int(sum));
}
//*************************************************************************
TEST(test_checksum_add_values8_operator_stream)
{
std::string data("123456789");
etl::checksum<uint8_t> checksum_calculator;
for (size_t i = 0; i < data.size(); ++i)
{
checksum_calculator << data[i];
}
uint8_t sum = checksum_calculator;
CHECK_EQUAL(221, int(sum));
}
//*************************************************************************
TEST(test_checksum_add_values32_add)
{
std::vector<uint32_t> data = { 0x04030201, 0x08070605 };
etl::checksum<uint32_t> checksum_calculator;
for (size_t i = 0; i < data.size(); ++i)
{
checksum_calculator += data[i];
}
uint32_t sum = checksum_calculator;
CHECK_EQUAL(36, int(sum));
}
//*************************************************************************
TEST(test_checksum_add_values32_plus_equals)
{
std::vector<uint32_t> data = { 0x04030201, 0x08070605 };
etl::checksum<uint32_t> checksum_calculator;
for (size_t i = 0; i < data.size(); ++i)
{
checksum_calculator.add(data[i]);
}
uint32_t sum = checksum_calculator;
uint8_t sum = checksum_calculator;
CHECK_EQUAL(36, int(sum));
}
//*************************************************************************
TEST(test_checksum_add_values32_operator_stream)
{
std::vector<uint32_t> data = { 0x04030201, 0x08070605 };
etl::checksum<uint32_t> checksum_calculator;
for (size_t i = 0; i < data.size(); ++i)
{
checksum_calculator << data[i];
}
uint32_t sum = checksum_calculator;
CHECK_EQUAL(36, int(sum));
CHECK_EQUAL(221, int(sum));
}
//*************************************************************************
@ -165,6 +97,20 @@ namespace
CHECK_EQUAL(221, int(sum));
}
//*************************************************************************
TEST(test_checksum_add_range_sum16)
{
std::string data("123456789");
etl::checksum<uint16_t> checksum_calculator;
checksum_calculator.add(data.begin(), data.end());
uint16_t sum = checksum_calculator.value();
CHECK_EQUAL(477, int(sum));
}
//*************************************************************************
TEST(test_checksum_add_range_sum32)
{
@ -184,58 +130,14 @@ namespace
{
std::vector<uint8_t> data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
std::vector<uint32_t> data2 = { 0x04030201, 0x08070605 };
std::vector<uint32_t> data3 = { 0x01020304, 0x05060708 };
std::vector<uint8_t> data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };
uint8_t sum1 = etl::checksum<uint8_t, etl::endian::little>(data1.begin(), data1.end());
uint8_t sum2 = etl::checksum<uint8_t, etl::endian::little>(data2.begin(), data2.end());
CHECK_EQUAL(int(sum1), int(sum2));
uint32_t hash1 = etl::checksum<uint32_t>(data1.begin(), data1.end());
uint32_t hash2 = etl::checksum<uint32_t>((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size()));
CHECK_EQUAL(int(hash1), int(hash2));
uint8_t sum3 = etl::checksum<uint8_t, etl::endian::big>(data3.begin(), data3.end());
CHECK_EQUAL(int(sum1), int(sum3));
}
//*************************************************************************
TEST(test_checksum_add_double)
{
double d = 3.1415927;
etl::checksum<uint8_t> checksum_calculator;
checksum_calculator << d;
uint8_t sum = checksum_calculator.value();
CHECK_EQUAL(165, int(sum));
}
//*************************************************************************
TEST(test_digest)
{
std::string data("123456789");
etl::checksum<uint8_t> checksum_calculator8(data.begin(), data.end());
etl::checksum<uint16_t> checksum_calculator16(data.begin(), data.end());
etl::checksum<uint32_t> checksum_calculator32(data.begin(), data.end());
etl::checksum<uint64_t> checksum_calculator64(data.begin(), data.end());
etl::ihash::generic_digest digest;
digest = checksum_calculator8.digest();
CHECK_EQUAL(221, *digest.first);
CHECK_EQUAL(sizeof(uint8_t), std::distance(digest.first, digest.second));
digest = checksum_calculator16.digest();
CHECK_EQUAL(477, *reinterpret_cast<const uint16_t*>(digest.first));
CHECK_EQUAL(sizeof(uint16_t), std::distance(digest.first, digest.second));
digest = checksum_calculator32.digest();
CHECK_EQUAL(477, *reinterpret_cast<const uint32_t*>(digest.first));
CHECK_EQUAL(sizeof(uint32_t), std::distance(digest.first, digest.second));
digest = checksum_calculator64.digest();
CHECK_EQUAL(477, *reinterpret_cast<const uint64_t*>(digest.first));
CHECK_EQUAL(sizeof(uint64_t), std::distance(digest.first, digest.second));
uint32_t hash3 = etl::checksum<uint32_t>(data3.rbegin(), data3.rend());
CHECK_EQUAL(int(hash1), int(hash3));
}
};
}

View File

@ -38,7 +38,6 @@ SOFTWARE.
#include "../crc16_kermit.h"
#include "../crc32.h"
#include "../crc64_ecma.h"
#include "../endian.h"
namespace
{
@ -49,7 +48,7 @@ namespace
{
std::string data("123456789");
uint8_t crc = etl::crc8_ccitt<>(data.begin(), data.end());
uint8_t crc = etl::crc8_ccitt(data.begin(), data.end());
CHECK_EQUAL(0xF4, int(crc));
}
@ -59,11 +58,11 @@ namespace
{
std::string data("123456789");
etl::crc8_ccitt<> crc_calculator;
etl::crc8_ccitt crc_calculator;
for (size_t i = 0; i < data.size(); ++i)
{
crc_calculator += data[i];
crc_calculator.add(data[i]);
}
uint8_t crc = crc_calculator;
@ -76,7 +75,7 @@ namespace
{
std::string data("123456789");
etl::crc8_ccitt<> crc_calculator;
etl::crc8_ccitt crc_calculator;
crc_calculator.add(data.begin(), data.end());
@ -90,13 +89,13 @@ namespace
{
std::vector<uint8_t> data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
std::vector<uint32_t> data2 = { 0x04030201, 0x08070605 };
std::vector<uint32_t> data3 = { 0x01020304, 0x05060708 };
std::vector<uint8_t> data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };
uint8_t crc1 = etl::crc8_ccitt<etl::endian::little>(data1.begin(), data1.end());
uint8_t crc2 = etl::crc8_ccitt<etl::endian::little>(data2.begin(), data2.end());
uint8_t crc1 = etl::crc32(data1.begin(), data1.end());
uint8_t crc2 = etl::crc32((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size()));
CHECK_EQUAL(int(crc1), int(crc2));
uint8_t crc3 = etl::crc8_ccitt<etl::endian::big>(data3.begin(), data3.end());
uint8_t crc3 = etl::crc32(data3.rbegin(), data3.rend());
CHECK_EQUAL(int(crc1), int(crc3));
}
@ -105,7 +104,7 @@ namespace
{
std::string data("123456789");
uint16_t crc = etl::crc16<>(data.begin(), data.end());
uint16_t crc = etl::crc16(data.begin(), data.end());
CHECK_EQUAL(0xBB3D, crc);
}
@ -115,11 +114,11 @@ namespace
{
std::string data("123456789");
etl::crc16<> crc_calculator;
etl::crc16 crc_calculator;
for (size_t i = 0; i < data.size(); ++i)
{
crc_calculator += data[i];
crc_calculator.add(data[i]);
}
uint16_t crc = crc_calculator;
@ -132,7 +131,7 @@ namespace
{
std::string data("123456789");
etl::crc16<> crc_calculator;
etl::crc16 crc_calculator;
crc_calculator.add(data.begin(), data.end());
@ -146,13 +145,13 @@ namespace
{
std::vector<uint8_t> data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
std::vector<uint32_t> data2 = { 0x04030201, 0x08070605 };
std::vector<uint32_t> data3 = { 0x01020304, 0x05060708 };
std::vector<uint8_t> data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };
uint16_t crc1 = etl::crc16<etl::endian::little>(data1.begin(), data1.end());
uint16_t crc2 = etl::crc16<etl::endian::little>(data2.begin(), data2.end());
uint16_t crc1 = etl::crc16(data1.begin(), data1.end());
uint16_t crc2 = etl::crc16((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size()));
CHECK_EQUAL(crc1, crc2);
uint16_t crc3 = etl::crc16<etl::endian::big>(data3.begin(), data3.end());
uint16_t crc3 = etl::crc16(data3.rbegin(), data3.rend());
CHECK_EQUAL(crc1, crc3);
}
@ -161,7 +160,7 @@ namespace
{
std::string data("123456789");
uint16_t crc = etl::crc16_ccitt<>(data.begin(), data.end());
uint16_t crc = etl::crc16_ccitt(data.begin(), data.end());
CHECK_EQUAL(0x29B1, crc);
}
@ -171,11 +170,11 @@ namespace
{
std::string data("123456789");
etl::crc16_ccitt<> crc_calculator;
etl::crc16_ccitt crc_calculator;
for (size_t i = 0; i < data.size(); ++i)
{
crc_calculator += data[i];
crc_calculator.add(data[i]);
}
uint16_t crc = crc_calculator;
@ -188,7 +187,7 @@ namespace
{
std::string data("123456789");
etl::crc16_ccitt<> crc_calculator;
etl::crc16_ccitt crc_calculator;
crc_calculator.add(data.begin(), data.end());
@ -202,13 +201,13 @@ namespace
{
std::vector<uint8_t> data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
std::vector<uint32_t> data2 = { 0x04030201, 0x08070605 };
std::vector<uint32_t> data3 = { 0x01020304, 0x05060708 };
std::vector<uint8_t> data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };
uint16_t crc1 = etl::crc16_ccitt<etl::endian::little>(data1.begin(), data1.end());
uint16_t crc2 = etl::crc16_ccitt<etl::endian::little>(data2.begin(), data2.end());
uint16_t crc1 = etl::crc16_ccitt(data1.begin(), data1.end());
uint16_t crc2 = etl::crc16_ccitt((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size()));
CHECK_EQUAL(crc1, crc2);
uint16_t crc3 = etl::crc16_ccitt<etl::endian::big>(data3.begin(), data3.end());
uint16_t crc3 = etl::crc16_ccitt(data3.rbegin(), data3.rend());
CHECK_EQUAL(crc1, crc3);
}
@ -217,7 +216,7 @@ namespace
{
std::string data("123456789");
uint16_t crc = etl::crc16_kermit<>(data.begin(), data.end());
uint16_t crc = etl::crc16_kermit(data.begin(), data.end());
CHECK_EQUAL(0x2189, crc);
}
@ -227,11 +226,11 @@ namespace
{
std::string data("123456789");
etl::crc16_kermit<> crc_calculator;
etl::crc16_kermit crc_calculator;
for (size_t i = 0; i < data.size(); ++i)
{
crc_calculator += data[i];
crc_calculator.add(data[i]);
}
uint16_t crc = crc_calculator;
@ -244,7 +243,7 @@ namespace
{
std::string data("123456789");
etl::crc16_kermit<> crc_calculator;
etl::crc16_kermit crc_calculator;
crc_calculator.add(data.begin(), data.end());
@ -258,13 +257,13 @@ namespace
{
std::vector<uint8_t> data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
std::vector<uint32_t> data2 = { 0x04030201, 0x08070605 };
std::vector<uint32_t> data3 = { 0x01020304, 0x05060708 };
std::vector<uint8_t> data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };
uint16_t crc1 = etl::crc16_kermit<etl::endian::little>(data1.begin(), data1.end());
uint16_t crc2 = etl::crc16_kermit<etl::endian::little>(data2.begin(), data2.end());
uint16_t crc1 = etl::crc16_kermit(data1.begin(), data1.end());
uint16_t crc2 = etl::crc16_kermit((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size()));
CHECK_EQUAL(crc1, crc2);
uint16_t crc3 = etl::crc16_kermit<etl::endian::big>(data3.begin(), data3.end());
uint16_t crc3 = etl::crc16_kermit(data3.rbegin(), data3.rend());
CHECK_EQUAL(crc1, crc3);
}
@ -273,7 +272,7 @@ namespace
{
std::string data("123456789");
uint32_t crc = etl::crc32<>(data.begin(), data.end());
uint32_t crc = etl::crc32(data.begin(), data.end());
CHECK_EQUAL(0xCBF43926, crc);
}
@ -283,15 +282,16 @@ namespace
{
std::string data("123456789");
etl::crc32<> crc_calculator;
etl::crc32 crc_calculator;
for (size_t i = 0; i < data.size(); ++i)
{
crc_calculator += data[i];
crc_calculator.add(data[i]);
}
uint32_t crc = crc_calculator;
CHECK_EQUAL(0xCBF43926, crc);
}
@ -300,7 +300,7 @@ namespace
{
std::string data("123456789");
etl::crc32<> crc_calculator;
etl::crc32 crc_calculator;
crc_calculator.add(data.begin(), data.end());
@ -314,13 +314,13 @@ namespace
{
std::vector<uint8_t> data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
std::vector<uint32_t> data2 = { 0x04030201, 0x08070605 };
std::vector<uint32_t> data3 = { 0x01020304, 0x05060708 };
std::vector<uint8_t> data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };
uint32_t crc1 = etl::crc32<etl::endian::little>(data1.begin(), data1.end());
uint32_t crc2 = etl::crc32<etl::endian::little>(data2.begin(), data2.end());
uint32_t crc1 = etl::crc32(data1.begin(), data1.end());
uint32_t crc2 = etl::crc32((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size()));
CHECK_EQUAL(crc1, crc2);
uint32_t crc3 = etl::crc32<etl::endian::big>(data3.begin(), data3.end());
uint32_t crc3 = etl::crc32(data3.rbegin(), data3.rend());
CHECK_EQUAL(crc1, crc3);
}
@ -329,7 +329,7 @@ namespace
{
std::string data("123456789");
uint64_t crc = etl::crc64_ecma<>(data.begin(), data.end());
uint64_t crc = etl::crc64_ecma(data.begin(), data.end());
CHECK_EQUAL(0x6C40DF5F0B497347, crc);
}
@ -339,11 +339,11 @@ namespace
{
std::string data("123456789");
etl::crc64_ecma<> crc_calculator;
etl::crc64_ecma crc_calculator;
for (size_t i = 0; i < data.size(); ++i)
{
crc_calculator += data[i];
crc_calculator.add(data[i]);
}
uint64_t crc = crc_calculator;
@ -356,7 +356,7 @@ namespace
{
std::string data("123456789");
etl::crc64_ecma<> crc_calculator;
etl::crc64_ecma crc_calculator;
crc_calculator.add(data.begin(), data.end());
@ -370,13 +370,13 @@ namespace
{
std::vector<uint8_t> data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
std::vector<uint32_t> data2 = { 0x04030201, 0x08070605 };
std::vector<uint32_t> data3 = { 0x01020304, 0x05060708 };
std::vector<uint8_t> data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };
uint64_t crc1 = etl::crc64_ecma<etl::endian::little>(data1.begin(), data1.end());
uint64_t crc2 = etl::crc64_ecma<etl::endian::little>(data2.begin(), data2.end());
uint64_t crc1 = etl::crc64_ecma(data1.begin(), data1.end());
uint64_t crc2 = etl::crc64_ecma((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size()));
CHECK_EQUAL(crc1, crc2);
uint64_t crc3 = etl::crc64_ecma<etl::endian::big>(data3.begin(), data3.end());
uint64_t crc3 = etl::crc64_ecma(data3.rbegin(), data3.rend());
CHECK_EQUAL(crc1, crc3);
}
};

View File

@ -34,7 +34,7 @@ SOFTWARE.
template <typename TIterator>
std::ostream& operator << (std::ostream& os, const etl::fixed_iterator<TIterator>& fi)
{
os << fi.get();
os << TIterator(fi);
return os;
}
@ -48,7 +48,7 @@ namespace
{
etl::fixed_iterator<int*> fi;
CHECK_EQUAL((int*)0, fi.get());
CHECK_EQUAL((int*)0, fi);
}
//*************************************************************************
@ -69,7 +69,7 @@ namespace
etl::fixed_iterator<int*> fi(&a);
CHECK_EQUAL(&a, fi.get());
CHECK_EQUAL(&a, fi);
}
//*************************************************************************
@ -79,7 +79,7 @@ namespace
etl::fixed_iterator<int*> fi = etl::make_fixed_iterator(&a);
CHECK_EQUAL(&a, fi.get());
CHECK_EQUAL(&a, fi);
}
//*************************************************************************
@ -202,11 +202,11 @@ namespace
etl::fixed_iterator<int*> fi = etl::make_fixed_iterator<int*>(&a);
fi = &b;
CHECK_EQUAL(&b, fi.get());
CHECK_EQUAL(&b, fi);
fi.set(&a);
fi = &a;
CHECK_EQUAL(&a, fi.get());
CHECK_EQUAL(&a, fi);
}
//*************************************************************************

View File

@ -228,16 +228,16 @@ namespace
DataNDC data(compare_data.begin(), compare_data.end());
//CHECK_EQUAL(data[0], compare_data[0]);
//CHECK_EQUAL(data[1], compare_data[1]);
//CHECK_EQUAL(data[2], compare_data[2]);
//CHECK_EQUAL(data[3], compare_data[3]);
//CHECK_EQUAL(data[4], compare_data[4]);
//CHECK_EQUAL(data[5], compare_data[5]);
//CHECK_EQUAL(data[6], compare_data[6]);
//CHECK_EQUAL(data[7], compare_data[7]);
//CHECK_EQUAL(data[8], compare_data[8]);
//CHECK_EQUAL(data[9], compare_data[9]);
CHECK_EQUAL(compare_data[0], data[0]);
CHECK_EQUAL(compare_data[1], data[1]);
CHECK_EQUAL(compare_data[2], data[2]);
CHECK_EQUAL(compare_data[3], data[3]);
CHECK_EQUAL(compare_data[4], data[4]);
CHECK_EQUAL(compare_data[5], data[5]);
CHECK_EQUAL(compare_data[6], data[6]);
CHECK_EQUAL(compare_data[7], data[7]);
CHECK_EQUAL(compare_data[8], data[8]);
CHECK_EQUAL(compare_data[9], data[9]);
}
//*************************************************************************

587
test/test_flat_multimap.cpp Normal file
View File

@ -0,0 +1,587 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
Copyright(c) 2015 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include <UnitTest++/UnitTest++.h>
#include <map>
#include <array>
#include <algorithm>
#include <utility>
#include <iterator>
#include <string>
#include <vector>
#include "data.h"
#include "../flat_multimap.h"
namespace
{
SUITE(test_flat_multimap)
{
static const size_t SIZE = 10;
typedef TestDataDC<std::string> DC;
typedef TestDataNDC<std::string> NDC;
typedef std::pair<int, DC> ElementDC;
typedef std::pair<int, NDC> ElementNDC;
typedef etl::flat_multimap<int, DC, SIZE> DataDC;
typedef etl::flat_multimap<int, NDC, SIZE> DataNDC;
typedef std::multimap<int, DC> Compare_DataDC;
typedef std::multimap<int, NDC> Compare_DataNDC;
NDC N0 = NDC("A");
NDC N1 = NDC("B");
NDC N2 = NDC("C");
NDC N3 = NDC("D");
NDC N4 = NDC("E");
NDC N5 = NDC("F");
NDC N6 = NDC("G");
NDC N7 = NDC("H");
NDC N8 = NDC("I");
NDC N9 = NDC("J");
NDC N10 = NDC("K");
NDC N11 = NDC("L");
NDC N12 = NDC("M");
NDC N13 = NDC("N");
NDC N14 = NDC("O");
NDC N15 = NDC("P");
NDC N16 = NDC("Q");
NDC N17 = NDC("R");
NDC N18 = NDC("S");
NDC N19 = NDC("T");
std::vector<ElementNDC> initial_data;
std::vector<ElementNDC> excess_data;
std::vector<ElementNDC> different_data;
std::vector<ElementNDC> multi_data;
//*************************************************************************
template <typename T1, typename T2>
bool Check_Equal(T1 begin1, T1 end1, T2 begin2)
{
while (begin1 != end1)
{
if ((begin1->first != begin2->first) || (begin1->second != begin2->second))
{
return false;
}
++begin1;
++begin2;
}
return true;
}
//*************************************************************************
struct SetupFixture
{
SetupFixture()
{
ElementNDC n[] =
{
ElementNDC(0, N0), ElementNDC(1, N1), ElementNDC(2, N2), ElementNDC(3, N3), ElementNDC(4, N4),
ElementNDC(5, N5), ElementNDC(6, N6), ElementNDC(7, N7), ElementNDC(8, N8), ElementNDC(9, N9)
};
ElementNDC n2[] =
{
ElementNDC(0, N0), ElementNDC(1, N1), ElementNDC(2, N2), ElementNDC(3, N3), ElementNDC(4, N4),
ElementNDC(5, N5), ElementNDC(6, N6), ElementNDC(7, N7), ElementNDC(8, N8), ElementNDC(9, N9),
ElementNDC(10, N10)
};
ElementNDC n3[] =
{
ElementNDC(10, N10), ElementNDC(11, N11), ElementNDC(12, N12), ElementNDC(13, N13), ElementNDC(14, N14),
ElementNDC(15, N15), ElementNDC(16, N16), ElementNDC(17, N17), ElementNDC(18, N18), ElementNDC(19, N19)
};
ElementNDC n4[] =
{
ElementNDC(0, N0), ElementNDC(1, N1), ElementNDC(2, N2), ElementNDC(1, N3), ElementNDC(3, N4),
ElementNDC(4, N5), ElementNDC(4, N6), ElementNDC(5, N7), ElementNDC(4, N8), ElementNDC(0, N9)
};
initial_data.assign(std::begin(n), std::end(n));
excess_data.assign(std::begin(n2), std::end(n2));
different_data.assign(std::begin(n3), std::end(n3));
multi_data.assign(std::begin(n4), std::end(n4));
}
};
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_default_constructor)
{
DataDC data;
CHECK_EQUAL(data.size(), size_t(0));
CHECK(data.empty());
CHECK_EQUAL(data.capacity(), SIZE);
CHECK_EQUAL(data.max_size(), SIZE);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_constructor_range)
{
Compare_DataNDC compare_data(initial_data.begin(), initial_data.end());
DataNDC data(compare_data.begin(), compare_data.end());
CHECK(data.size() == SIZE);
CHECK(!data.empty());
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_assignment)
{
DataNDC data(initial_data.begin(), initial_data.end());
DataNDC other_data;
other_data = data;
bool isEqual = Check_Equal(data.begin(),
data.end(),
other_data.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_self_assignment)
{
DataNDC data(initial_data.begin(), initial_data.end());
DataNDC other_data(data);
other_data = other_data;
bool isEqual = Check_Equal(data.begin(),
data.end(),
other_data.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_begin)
{
DataNDC data(initial_data.begin(), initial_data.end());
const DataNDC constData(data);
CHECK_EQUAL(data.begin(), std::begin(data));
CHECK_EQUAL(constData.begin(), std::begin(constData));
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_end)
{
DataNDC data(initial_data.begin(), initial_data.end());
const DataNDC constData(data);
CHECK_EQUAL(data.end(), std::end(data));
CHECK_EQUAL(constData.end(), std::end(constData));
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_empty)
{
DataNDC data;
data.insert(initial_data.begin(), initial_data.end());
CHECK(data.full());
CHECK(!data.empty());
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_full)
{
DataDC data;
CHECK(!data.full());
CHECK(data.empty());
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_assign_range)
{
Compare_DataNDC compare_data(initial_data.begin(), initial_data.end());
DataNDC data;
data.assign(compare_data.begin(), compare_data.end());
bool isEqual = Check_Equal(data.begin(),
data.end(),
compare_data.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_insert_value)
{
Compare_DataNDC compare_data;
DataNDC data;
data.insert(DataNDC::value_type(0, N0));
compare_data.insert(std::make_pair(0, N0));
bool isEqual = Check_Equal(data.begin(),
data.end(),
compare_data.begin());
CHECK(isEqual);
data.insert(std::make_pair(2, N2));
compare_data.insert(std::make_pair(2, N2));
isEqual = Check_Equal(data.begin(),
data.end(),
compare_data.begin());
CHECK(isEqual);
data.insert(std::make_pair(1, N1));
compare_data.insert(std::make_pair(1, N1));
isEqual = Check_Equal(data.begin(),
data.end(),
compare_data.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_insert_value_excess)
{
DataNDC data(initial_data.begin(), initial_data.end());
CHECK_THROW(data.insert(std::make_pair(10, N10)), etl::flat_multimap_full);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_insert_range)
{
Compare_DataNDC compare_data;
DataNDC data;
data.insert(initial_data.begin(), initial_data.end());
compare_data.insert(initial_data.begin(), initial_data.end());
bool isEqual = Check_Equal(data.begin(),
data.end(),
compare_data.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_insert_range_excess)
{
DataNDC data;
CHECK_THROW(data.insert(excess_data.begin(), excess_data.end()), etl::flat_multimap_full);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_erase_key)
{
Compare_DataNDC compare_data(initial_data.begin(), initial_data.end());
DataNDC data(initial_data.begin(), initial_data.end());
Compare_DataNDC::iterator i_compare = compare_data.begin();
DataNDC::iterator i_data = data.begin();
size_t count_compare = compare_data.erase(5);
size_t count = data.erase(5);
CHECK_EQUAL(count_compare, count);
bool isEqual = Check_Equal(data.begin(),
data.end(),
compare_data.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_erase_single)
{
Compare_DataNDC compare_data(initial_data.begin(), initial_data.end());
DataNDC data(initial_data.begin(), initial_data.end());
Compare_DataNDC::iterator i_compare = compare_data.begin();
DataNDC::iterator i_data = data.begin();
std::advance(i_compare, 2);
std::advance(i_data, 2);
compare_data.erase(i_compare);
data.erase(i_data);
bool isEqual = Check_Equal(data.begin(),
data.end(),
compare_data.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_erase_range)
{
Compare_DataNDC compare_data(initial_data.begin(), initial_data.end());
DataNDC data(initial_data.begin(), initial_data.end());
Compare_DataNDC::iterator i_compare = compare_data.begin();
DataNDC::iterator i_data = data.begin();
Compare_DataNDC::iterator i_compare_end = compare_data.begin();
DataNDC::iterator i_data_end = data.begin();
std::advance(i_compare, 2);
std::advance(i_data, 2);
std::advance(i_compare_end, 4);
std::advance(i_data_end, 4);
compare_data.erase(i_compare, i_compare_end);
data.erase(i_data, i_data_end);
bool isEqual = Check_Equal(data.begin(),
data.end(),
compare_data.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_clear)
{
Compare_DataNDC compare_data(initial_data.begin(), initial_data.end());
DataNDC data(compare_data.begin(), compare_data.end());
data.clear();
CHECK_EQUAL(data.size(), size_t(0));
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_iterator)
{
Compare_DataNDC compare_data(initial_data.begin(), initial_data.end());
DataNDC data(compare_data.begin(), compare_data.end());
bool isEqual = Check_Equal(data.begin(),
data.end(),
compare_data.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_const_iterator)
{
Compare_DataNDC compare_data(initial_data.begin(), initial_data.end());
DataNDC data(compare_data.begin(), compare_data.end());
bool isEqual = Check_Equal(data.cbegin(),
data.cend(),
compare_data.cbegin());
CHECK(isEqual);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_reverse_iterator)
{
Compare_DataNDC compare_data(initial_data.begin(), initial_data.end());
DataNDC data(compare_data.begin(), compare_data.end());
bool isEqual = Check_Equal(data.rbegin(),
data.rend(),
compare_data.rbegin());
CHECK(isEqual);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_const_reverse_iterator)
{
Compare_DataNDC compare_data(initial_data.begin(), initial_data.end());
DataNDC data(compare_data.begin(), compare_data.end());
bool isEqual = Check_Equal(data.crbegin(),
data.crend(),
compare_data.crbegin());
CHECK(isEqual);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_find)
{
DataNDC data(initial_data.begin(), initial_data.end());
DataNDC::iterator it = data.find(3);
CHECK_EQUAL(N3, it->second);
it = data.find(19);
CHECK_EQUAL(data.end(), it);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_find_const)
{
const DataNDC data(initial_data.begin(), initial_data.end());
DataNDC::const_iterator it = data.find(3);
CHECK_EQUAL(N3, it->second);
it = data.find(19);
CHECK_EQUAL(data.end(), it);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_lower_bound)
{
Compare_DataNDC compare_data(initial_data.begin(), initial_data.end());
DataNDC data(initial_data.begin(), initial_data.end());
Compare_DataNDC::iterator i_compare = compare_data.lower_bound(5);
DataNDC::iterator i_data = data.lower_bound(5);
CHECK_EQUAL(std::distance(compare_data.begin(), i_compare), std::distance(data.begin(), i_data));
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_upper_bound)
{
Compare_DataNDC compare_data(initial_data.begin(), initial_data.end());
DataNDC data(initial_data.begin(), initial_data.end());
Compare_DataNDC::iterator i_compare = compare_data.upper_bound(5);
DataNDC::iterator i_data = data.upper_bound(5);
CHECK_EQUAL(std::distance(compare_data.begin(), i_compare), std::distance(data.begin(), i_data));
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_equal_range)
{
Compare_DataNDC compare_data(initial_data.begin(), initial_data.end());
DataNDC data(initial_data.begin(), initial_data.end());
std::pair<Compare_DataNDC::iterator, Compare_DataNDC::iterator> i_compare = compare_data.equal_range(5);
std::pair<DataNDC::iterator, DataNDC::iterator> i_data = data.equal_range(5);
CHECK_EQUAL(std::distance(compare_data.begin(), i_compare.first), std::distance(data.begin(), i_data.first));
CHECK_EQUAL(std::distance(compare_data.begin(), i_compare.second), std::distance(data.begin(), i_data.second));
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_equal)
{
const DataNDC initial1(initial_data.begin(), initial_data.end());
const DataNDC initial2(initial_data.begin(), initial_data.end());
CHECK(initial1 == initial2);
const DataNDC different(different_data.begin(), different_data.end());
CHECK(!(initial1 == different));
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_not_equal)
{
const DataNDC initial1(initial_data.begin(), initial_data.end());
const DataNDC initial2(initial_data.begin(), initial_data.end());
CHECK(!(initial1 != initial2));
const DataNDC different(different_data.begin(), different_data.end());
CHECK(initial1 != different);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_multi)
{
Compare_DataNDC compare_data(multi_data.begin(), multi_data.end());
DataNDC data(multi_data.begin(), multi_data.end());
std::pair<Compare_DataNDC::iterator, Compare_DataNDC::iterator> compare_range;
std::pair<DataNDC::iterator, DataNDC::iterator> test_range;
compare_range = compare_data.equal_range(0);
test_range = data.equal_range(0);
CHECK_EQUAL(std::distance(compare_range.first, compare_range.second), std::distance(test_range.first, test_range.second));
compare_range = compare_data.equal_range(1);
test_range = data.equal_range(1);
CHECK_EQUAL(std::distance(compare_range.first, compare_range.second), std::distance(test_range.first, test_range.second));
compare_range = compare_data.equal_range(2);
test_range = data.equal_range(2);
CHECK_EQUAL(std::distance(compare_range.first, compare_range.second), std::distance(test_range.first, test_range.second));
compare_range = compare_data.equal_range(3);
test_range = data.equal_range(3);
CHECK_EQUAL(std::distance(compare_range.first, compare_range.second), std::distance(test_range.first, test_range.second));
compare_range = compare_data.equal_range(4);
test_range = data.equal_range(4);
CHECK_EQUAL(std::distance(compare_range.first, compare_range.second), std::distance(test_range.first, test_range.second));
compare_range = compare_data.equal_range(5);
test_range = data.equal_range(5);
CHECK_EQUAL(std::distance(compare_range.first, compare_range.second), std::distance(test_range.first, test_range.second));
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_count)
{
Compare_DataNDC compare_data(multi_data.begin(), multi_data.end());
DataNDC data(multi_data.begin(), multi_data.end());
CHECK_EQUAL(compare_data.count(0), data.count(0));
CHECK_EQUAL(compare_data.count(1), data.count(1));
CHECK_EQUAL(compare_data.count(2), data.count(2));
CHECK_EQUAL(compare_data.count(3), data.count(3));
CHECK_EQUAL(compare_data.count(4), data.count(4));
CHECK_EQUAL(compare_data.count(5), data.count(5));
}
};
}

556
test/test_flat_multiset.cpp Normal file
View File

@ -0,0 +1,556 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
Copyright(c) 2015 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include <UnitTest++/UnitTest++.h>
#include <set>
#include <array>
#include <algorithm>
#include <utility>
#include <iterator>
#include <string>
#include <vector>
#include "data.h"
#include "../flat_multiset.h"
namespace
{
SUITE(test_flat_multiset)
{
static const size_t SIZE = 10;
typedef TestDataDC<std::string> DC;
typedef TestDataNDC<std::string> NDC;
typedef etl::flat_multiset<DC, SIZE> DataDC;
typedef etl::flat_multiset<NDC, SIZE> DataNDC;
typedef std::multiset<DC> Compare_DataDC;
typedef std::multiset<NDC> Compare_DataNDC;
NDC N0 = NDC("A");
NDC N1 = NDC("B");
NDC N2 = NDC("C");
NDC N3 = NDC("D");
NDC N4 = NDC("E");
NDC N5 = NDC("F");
NDC N6 = NDC("G");
NDC N7 = NDC("H");
NDC N8 = NDC("I");
NDC N9 = NDC("J");
NDC N10 = NDC("K");
NDC N11 = NDC("L");
NDC N12 = NDC("M");
NDC N13 = NDC("N");
NDC N14 = NDC("O");
NDC N15 = NDC("P");
NDC N16 = NDC("Q");
NDC N17 = NDC("R");
NDC N18 = NDC("S");
NDC N19 = NDC("T");
std::vector<NDC> initial_data;
std::vector<NDC> excess_data;
std::vector<NDC> different_data;
std::vector<NDC> multi_data;
//*************************************************************************
struct SetupFixture
{
SetupFixture()
{
NDC n[] =
{
N0, N1, N2, N3, N4, N5, N6, N7, N8, N9
};
NDC n2[] =
{
N0, N1, N2, N3, N4, N5, N6, N7, N8, N9, N10
};
NDC n3[] =
{
N10, N11, N12, N13, N14, N15, N16, N17, N18, N19
};
NDC n4[] =
{
N0, N0, N1, N2, N3, N1, N3, N3, N4, N2
};
initial_data.assign(std::begin(n), std::end(n));
excess_data.assign(std::begin(n2), std::end(n2));
different_data.assign(std::begin(n3), std::end(n3));
multi_data.assign(std::begin(n4), std::end(n4));
}
};
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_default_constructor)
{
DataDC data;
CHECK_EQUAL(data.size(), size_t(0));
CHECK(data.empty());
CHECK_EQUAL(data.capacity(), SIZE);
CHECK_EQUAL(data.max_size(), SIZE);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_constructor_range)
{
Compare_DataNDC compare_data(initial_data.begin(), initial_data.end());
DataNDC data(compare_data.begin(), compare_data.end());
CHECK(data.size() == SIZE);
CHECK(!data.empty());
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_assignment)
{
DataNDC data(initial_data.begin(), initial_data.end());
DataNDC other_data;
other_data = data;
bool isEqual = std::equal(data.begin(),
data.end(),
other_data.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_self_assignment)
{
DataNDC data(initial_data.begin(), initial_data.end());
DataNDC other_data(data);
other_data = other_data;
bool isEqual = std::equal(data.begin(),
data.end(),
other_data.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_begin)
{
DataNDC data(initial_data.begin(), initial_data.end());
const DataNDC constData(data);
CHECK_EQUAL(data.begin(), std::begin(data));
CHECK_EQUAL(constData.begin(), std::begin(constData));
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_end)
{
DataNDC data(initial_data.begin(), initial_data.end());
const DataNDC constData(data);
CHECK_EQUAL(data.end(), std::end(data));
CHECK_EQUAL(constData.end(), std::end(constData));
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_empty)
{
DataNDC data;
data.insert(initial_data.begin(), initial_data.end());
CHECK(data.full());
CHECK(!data.empty());
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_full)
{
DataNDC data;
CHECK(!data.full());
CHECK(data.empty());
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_assign_range)
{
Compare_DataNDC compare_data(initial_data.begin(), initial_data.end());
DataNDC data;
data.assign(compare_data.begin(), compare_data.end());
bool isEqual = std::equal(data.begin(),
data.end(),
compare_data.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_insert_value)
{
Compare_DataNDC compare_data;
DataNDC data;
data.insert(N0);
compare_data.insert(N0);
bool isEqual = std::equal(data.begin(),
data.end(),
compare_data.begin());
CHECK(isEqual);
data.insert(N2);
compare_data.insert(N2);
isEqual = std::equal(data.begin(),
data.end(),
compare_data.begin());
CHECK(isEqual);
data.insert(N1);
compare_data.insert(N1);
isEqual = std::equal(data.begin(),
data.end(),
compare_data.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_insert_value_excess)
{
DataNDC data(initial_data.begin(), initial_data.end());
CHECK_THROW(data.insert(N10), etl::flat_multiset_full);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_insert_range)
{
Compare_DataNDC compare_data;
DataNDC data;
data.insert(initial_data.begin(), initial_data.end());
compare_data.insert(initial_data.begin(), initial_data.end());
bool isEqual = std::equal(data.begin(),
data.end(),
compare_data.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_insert_range_excess)
{
DataNDC data;
CHECK_THROW(data.insert(excess_data.begin(), excess_data.end()), etl::flat_multiset_full);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_erase_key)
{
Compare_DataNDC compare_data(initial_data.begin(), initial_data.end());
DataNDC data(initial_data.begin(), initial_data.end());
Compare_DataNDC::iterator i_compare = compare_data.begin();
DataNDC::iterator i_data = data.begin();
size_t count_compare = compare_data.erase(N5);
size_t count = data.erase(N5);
CHECK_EQUAL(count_compare, count);
bool isEqual = std::equal(data.begin(),
data.end(),
compare_data.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_erase_single)
{
Compare_DataNDC compare_data(initial_data.begin(), initial_data.end());
DataNDC data(initial_data.begin(), initial_data.end());
Compare_DataNDC::iterator i_compare = compare_data.begin();
DataNDC::iterator i_data = data.begin();
std::advance(i_compare, 2);
std::advance(i_data, 2);
compare_data.erase(i_compare);
data.erase(i_data);
bool isEqual = std::equal(data.begin(),
data.end(),
compare_data.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_erase_range)
{
Compare_DataNDC compare_data(initial_data.begin(), initial_data.end());
DataNDC data(initial_data.begin(), initial_data.end());
Compare_DataNDC::iterator i_compare = compare_data.begin();
DataNDC::iterator i_data = data.begin();
Compare_DataNDC::iterator i_compare_end = compare_data.begin();
DataNDC::iterator i_data_end = data.begin();
std::advance(i_compare, 2);
std::advance(i_data, 2);
std::advance(i_compare_end, 4);
std::advance(i_data_end, 4);
compare_data.erase(i_compare, i_compare_end);
data.erase(i_data, i_data_end);
bool isEqual = std::equal(data.begin(),
data.end(),
compare_data.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_clear)
{
Compare_DataNDC compare_data(initial_data.begin(), initial_data.end());
DataNDC data(compare_data.begin(), compare_data.end());
data.clear();
CHECK_EQUAL(data.size(), size_t(0));
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_iterator)
{
Compare_DataNDC compare_data(initial_data.begin(), initial_data.end());
DataNDC data(compare_data.begin(), compare_data.end());
bool isEqual = std::equal(data.begin(),
data.end(),
compare_data.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_const_iterator)
{
Compare_DataNDC compare_data(initial_data.begin(), initial_data.end());
DataNDC data(compare_data.begin(), compare_data.end());
bool isEqual = std::equal(data.cbegin(),
data.cend(),
compare_data.cbegin());
CHECK(isEqual);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_reverse_iterator)
{
Compare_DataNDC compare_data(initial_data.begin(), initial_data.end());
DataNDC data(compare_data.begin(), compare_data.end());
bool isEqual = std::equal(data.rbegin(),
data.rend(),
compare_data.rbegin());
CHECK(isEqual);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_const_reverse_iterator)
{
Compare_DataNDC compare_data(initial_data.begin(), initial_data.end());
DataNDC data(compare_data.begin(), compare_data.end());
bool isEqual = std::equal(data.crbegin(),
data.crend(),
compare_data.crbegin());
CHECK(isEqual);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_find)
{
DataNDC data(initial_data.begin(), initial_data.end());
DataNDC::iterator it = data.find(N3);
CHECK_EQUAL(N3, *it);
it = data.find(N19);
CHECK_EQUAL(data.end(), it);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_find_const)
{
const DataNDC data(initial_data.begin(), initial_data.end());
DataNDC::const_iterator it = data.find(N3);
CHECK_EQUAL(N3, *it);
it = data.find(N19);
CHECK_EQUAL(data.end(), it);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_lower_bound)
{
Compare_DataNDC compare_data(initial_data.begin(), initial_data.end());
DataNDC data(initial_data.begin(), initial_data.end());
Compare_DataNDC::iterator i_compare = compare_data.lower_bound(N5);
DataNDC::iterator i_data = data.lower_bound(N5);
CHECK_EQUAL(std::distance(compare_data.begin(), i_compare), std::distance(data.begin(), i_data));
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_upper_bound)
{
Compare_DataNDC compare_data(initial_data.begin(), initial_data.end());
DataNDC data(initial_data.begin(), initial_data.end());
Compare_DataNDC::iterator i_compare = compare_data.upper_bound(N5);
DataNDC::iterator i_data = data.upper_bound(N5);
CHECK_EQUAL(std::distance(compare_data.begin(), i_compare), std::distance(data.begin(), i_data));
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_equal_range)
{
Compare_DataNDC compare_data(initial_data.begin(), initial_data.end());
DataNDC data(initial_data.begin(), initial_data.end());
std::pair<Compare_DataNDC::iterator, Compare_DataNDC::iterator> i_compare = compare_data.equal_range(N5);
std::pair<DataNDC::iterator, DataNDC::iterator> i_data = data.equal_range(N5);
CHECK_EQUAL(std::distance(compare_data.begin(), i_compare.first), std::distance(data.begin(), i_data.first));
CHECK_EQUAL(std::distance(compare_data.begin(), i_compare.second), std::distance(data.begin(), i_data.second));
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_equal)
{
const DataNDC initial1(initial_data.begin(), initial_data.end());
const DataNDC initial2(initial_data.begin(), initial_data.end());
CHECK(initial1 == initial2);
const DataNDC different(different_data.begin(), different_data.end());
CHECK(!(initial1 == different));
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_not_equal)
{
const DataNDC initial1(initial_data.begin(), initial_data.end());
const DataNDC initial2(initial_data.begin(), initial_data.end());
CHECK(!(initial1 != initial2));
const DataNDC different(different_data.begin(), different_data.end());
CHECK(initial1 != different);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_multi)
{
Compare_DataNDC compare_data(multi_data.begin(), multi_data.end());
DataNDC data(multi_data.begin(), multi_data.end());
std::pair<Compare_DataNDC::iterator, Compare_DataNDC::iterator> compare_range;
std::pair<DataNDC::iterator, DataNDC::iterator> test_range;
compare_range = compare_data.equal_range(N0);
test_range = data.equal_range(N0);
CHECK_EQUAL(std::distance(compare_range.first, compare_range.second), std::distance(test_range.first, test_range.second));
compare_range = compare_data.equal_range(N1);
test_range = data.equal_range(N1);
CHECK_EQUAL(std::distance(compare_range.first, compare_range.second), std::distance(test_range.first, test_range.second));
compare_range = compare_data.equal_range(N2);
test_range = data.equal_range(N2);
CHECK_EQUAL(std::distance(compare_range.first, compare_range.second), std::distance(test_range.first, test_range.second));
compare_range = compare_data.equal_range(N3);
test_range = data.equal_range(N3);
CHECK_EQUAL(std::distance(compare_range.first, compare_range.second), std::distance(test_range.first, test_range.second));
compare_range = compare_data.equal_range(N4);
test_range = data.equal_range(N4);
CHECK_EQUAL(std::distance(compare_range.first, compare_range.second), std::distance(test_range.first, test_range.second));
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_count)
{
Compare_DataNDC compare_data(multi_data.begin(), multi_data.end());
DataNDC data(multi_data.begin(), multi_data.end());
CHECK_EQUAL(compare_data.count(N0), data.count(N0));
CHECK_EQUAL(compare_data.count(N1), data.count(N1));
CHECK_EQUAL(compare_data.count(N2), data.count(N2));
CHECK_EQUAL(compare_data.count(N3), data.count(N3));
CHECK_EQUAL(compare_data.count(N4), data.count(N4));
}
};
}

View File

@ -33,7 +33,6 @@ SOFTWARE.
#include <stdint.h>
#include "../fnv_1.h"
#include "../endian.h"
namespace
{
@ -44,7 +43,7 @@ namespace
{
std::string data("123456789");
uint32_t hash = etl::fnv_1_32<>(data.begin(), data.end());
uint32_t hash = etl::fnv_1_32(data.begin(), data.end());
CHECK_EQUAL(0x24148816, hash);
}
@ -54,14 +53,14 @@ namespace
{
std::string data("123456789");
etl::fnv_1_32<> fnv_1_32_calculator;
etl::fnv_1_32 fnv_1_32_calculator;
for (size_t i = 0; i < data.size(); ++i)
{
fnv_1_32_calculator += data[i];
fnv_1_32_calculator.add(data[i]);
}
uint32_t hash = fnv_1_32_calculator;
uint32_t hash = fnv_1_32_calculator.value();
CHECK_EQUAL(0x24148816, hash);
}
@ -71,7 +70,7 @@ namespace
{
std::string data("123456789");
etl::fnv_1_32<> fnv_1_32_calculator;
etl::fnv_1_32 fnv_1_32_calculator;
fnv_1_32_calculator.add(data.begin(), data.end());
@ -85,14 +84,14 @@ namespace
{
std::vector<uint8_t> data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
std::vector<uint32_t> data2 = { 0x04030201, 0x08070605 };
std::vector<uint32_t> data3 = { 0x01020304, 0x05060708 };
std::vector<uint8_t> data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };
uint32_t hash1 = etl::fnv_1_32<etl::endian::little>(data1.begin(), data1.end());
uint32_t hash2 = etl::fnv_1_32<etl::endian::little>(data2.begin(), data2.end());
CHECK_EQUAL(hash1, hash2);
uint32_t hash1 = etl::fnv_1_32(data1.begin(), data1.end());
uint32_t hash2 = etl::fnv_1_32((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size()));
CHECK_EQUAL(int(hash1), int(hash2));
uint32_t hash3 = etl::fnv_1_32<etl::endian::big>(data3.begin(), data3.end());
CHECK_EQUAL(hash1, hash3);
uint32_t hash3 = etl::fnv_1_32(data3.rbegin(), data3.rend());
CHECK_EQUAL(int(hash1), int(hash3));
}
//*************************************************************************
@ -100,7 +99,7 @@ namespace
{
std::string data("123456789");
uint32_t hash = etl::fnv_1a_32<>(data.begin(), data.end());
uint32_t hash = etl::fnv_1a_32(data.begin(), data.end());
CHECK_EQUAL(0xBB86B11C, hash);
}
@ -110,14 +109,14 @@ namespace
{
std::string data("123456789");
etl::fnv_1a_32<> fnv_1a_32_calculator;
etl::fnv_1a_32 fnv_1a_32_calculator;
for (size_t i = 0; i < data.size(); ++i)
{
fnv_1a_32_calculator += data[i];
fnv_1a_32_calculator.add(data[i]);
}
uint32_t hash = fnv_1a_32_calculator;
uint32_t hash = fnv_1a_32_calculator.value();
CHECK_EQUAL(0xBB86B11C, hash);
}
@ -127,7 +126,7 @@ namespace
{
std::string data("123456789");
etl::fnv_1a_32<> fnv_1a_32_calculator;
etl::fnv_1a_32 fnv_1a_32_calculator;
fnv_1a_32_calculator.add(data.begin(), data.end());
@ -141,14 +140,14 @@ namespace
{
std::vector<uint8_t> data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
std::vector<uint32_t> data2 = { 0x04030201, 0x08070605 };
std::vector<uint32_t> data3 = { 0x01020304, 0x05060708 };
std::vector<uint8_t> data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };
uint32_t hash1 = etl::fnv_1a_32<etl::endian::little>(data1.begin(), data1.end());
uint32_t hash2 = etl::fnv_1a_32<etl::endian::little>(data2.begin(), data2.end());
CHECK_EQUAL(hash1, hash2);
uint32_t hash1 = etl::fnv_1a_32(data1.begin(), data1.end());
uint32_t hash2 = etl::fnv_1a_32((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size()));
CHECK_EQUAL(int(hash1), int(hash2));
uint32_t hash3 = etl::fnv_1a_32<etl::endian::big>(data3.begin(), data3.end());
CHECK_EQUAL(hash1, hash3);
uint32_t hash3 = etl::fnv_1a_32(data3.rbegin(), data3.rend());
CHECK_EQUAL(int(hash1), int(hash3));
}
//*************************************************************************
@ -156,7 +155,7 @@ namespace
{
std::string data("123456789");
uint64_t hash = etl::fnv_1_64<>(data.begin(), data.end());
uint64_t hash = etl::fnv_1_64(data.begin(), data.end());
CHECK_EQUAL(0xA72FFC362BF916D6, hash);
}
@ -166,11 +165,11 @@ namespace
{
std::string data("123456789");
etl::fnv_1_64<> fnv_1_64_calculator;
etl::fnv_1_64 fnv_1_64_calculator;
for (size_t i = 0; i < data.size(); ++i)
{
fnv_1_64_calculator += data[i];
fnv_1_64_calculator.add(data[i]);
}
uint64_t hash = fnv_1_64_calculator;
@ -183,7 +182,7 @@ namespace
{
std::string data("123456789");
etl::fnv_1_64<> fnv_1_64_calculator;
etl::fnv_1_64 fnv_1_64_calculator;
fnv_1_64_calculator.add(data.begin(), data.end());
@ -197,14 +196,14 @@ namespace
{
std::vector<uint8_t> data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
std::vector<uint32_t> data2 = { 0x04030201, 0x08070605 };
std::vector<uint32_t> data3 = { 0x01020304, 0x05060708 };
std::vector<uint8_t> data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };
uint64_t hash1 = etl::fnv_1_64<etl::endian::little>(data1.begin(), data1.end());
uint64_t hash2 = etl::fnv_1_64<etl::endian::little>(data2.begin(), data2.end());
CHECK_EQUAL(hash1, hash2);
uint64_t hash1 = etl::fnv_1_64(data1.begin(), data1.end());
uint64_t hash2 = etl::fnv_1_64((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size()));
CHECK_EQUAL(int(hash1), int(hash2));
uint64_t hash3 = etl::fnv_1_64<etl::endian::big>(data3.begin(), data3.end());
CHECK_EQUAL(hash1, hash3);
uint64_t hash3 = etl::fnv_1_64(data3.rbegin(), data3.rend());
CHECK_EQUAL(int(hash1), int(hash3));
}
//*************************************************************************
@ -212,7 +211,7 @@ namespace
{
std::string data("123456789");
uint64_t hash = etl::fnv_1a_64<>(data.begin(), data.end());
uint64_t hash = etl::fnv_1a_64(data.begin(), data.end());
CHECK_EQUAL(0x06D5573923C6CDFC, hash);
}
@ -222,11 +221,11 @@ namespace
{
std::string data("123456789");
etl::fnv_1a_64<> fnv_1a_64_calculator;
etl::fnv_1a_64 fnv_1a_64_calculator;
for (size_t i = 0; i < data.size(); ++i)
{
fnv_1a_64_calculator += data[i];
fnv_1a_64_calculator.add(data[i]);
}
uint64_t hash = fnv_1a_64_calculator;
@ -239,7 +238,7 @@ namespace
{
std::string data("123456789");
etl::fnv_1a_64<> fnv_1a_64_calculator;
etl::fnv_1a_64 fnv_1a_64_calculator;
fnv_1a_64_calculator.add(data.begin(), data.end());
@ -253,14 +252,14 @@ namespace
{
std::vector<uint8_t> data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
std::vector<uint32_t> data2 = { 0x04030201, 0x08070605 };
std::vector<uint32_t> data3 = { 0x01020304, 0x05060708 };
std::vector<uint8_t> data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };
uint64_t hash1 = etl::fnv_1a_64<etl::endian::little>(data1.begin(), data1.end());
uint64_t hash2 = etl::fnv_1a_64<etl::endian::little>(data2.begin(), data2.end());
CHECK_EQUAL(hash1, hash2);
uint64_t hash1 = etl::fnv_1a_64(data1.begin(), data1.end());
uint64_t hash2 = etl::fnv_1a_64((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size()));
CHECK_EQUAL(int(hash1), int(hash2));
uint64_t hash3 = etl::fnv_1a_64<etl::endian::big>(data3.begin(), data3.end());
CHECK_EQUAL(hash1, hash3);
uint64_t hash3 = etl::fnv_1a_64(data3.rbegin(), data3.rend());
CHECK_EQUAL(int(hash1), int(hash3));
}
};
}

220
test/test_jenkins.cpp Normal file
View File

@ -0,0 +1,220 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
Copyright(c) 2014 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include <UnitTest++/UnitTest++.h>
#include "murmurhash3.h" // The 'C' reference implementation.
#include <iterator>
#include <string>
#include <vector>
#include <stdint.h>
#include "../jenkins.h"
#include "../endian.h"
template <typename TIterator>
uint32_t jenkins32(TIterator begin, TIterator end)
{
uint32_t hash = 0;
while (begin != end)
{
hash += *begin++;
hash += (hash << 10);
hash ^= (hash >> 6);
}
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
return hash;
}
template <typename TIterator>
uint64_t jenkins64(TIterator begin, TIterator end)
{
uint64_t hash = 0;
while (begin != end)
{
hash += *begin++;
hash += (hash << 10);
hash ^= (hash >> 6);
}
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
return hash;
}
namespace
{
SUITE(test_jenkins)
{
//*************************************************************************
TEST(test_jenkins_32_constructor)
{
std::string data("123456789");
uint32_t hash = etl::jenkins<uint32_t>(data.begin(), data.end());
uint32_t compare = jenkins32(data.begin(), data.end());
CHECK_EQUAL(compare, hash);
}
//*************************************************************************
TEST(test_jenkins_32_add_values)
{
std::string data("123456789");
etl::jenkins<uint32_t> jenkins_32_calculator;
for (size_t i = 0; i < data.size(); ++i)
{
jenkins_32_calculator.add(data[i]);
}
uint32_t hash = jenkins_32_calculator;
uint32_t compare = jenkins32(data.begin(), data.end());
CHECK_EQUAL(compare, hash);
}
//*************************************************************************
TEST(test_jenkins_32_add_range)
{
std::string data("123456789");
etl::jenkins<uint32_t> jenkins_32_calculator;
jenkins_32_calculator.add(data.begin(), data.end());
uint32_t hash = jenkins_32_calculator.value();
uint32_t compare = jenkins32(data.begin(), data.end());
CHECK_EQUAL(compare, hash);
}
//*************************************************************************
TEST(test_jenkins_32_add_range_endian)
{
std::vector<uint8_t> data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
std::vector<uint32_t> data2 = { 0x04030201, 0x08070605 };
std::vector<uint8_t> data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };
uint32_t hash1 = etl::jenkins<uint32_t>(data1.begin(), data1.end());
uint32_t hash2 = etl::jenkins<uint32_t>((uint8_t*)&data2[0], (uint8_t*)&data2[0] + (data2.size() * sizeof(uint32_t)));
uint32_t hash3 = etl::jenkins<uint32_t>(data3.rbegin(), data3.rend());
CHECK_EQUAL(hash1, hash2);
CHECK_EQUAL(hash1, hash3);
uint64_t compare1 = jenkins32(data1.begin(), data1.end());
CHECK_EQUAL(compare1, hash1);
uint64_t compare2 = jenkins32((uint8_t*)&data2[0], (uint8_t*)&data2[0] + (data2.size() * sizeof(uint32_t)));
CHECK_EQUAL(compare2, hash2);
uint64_t compare3 = jenkins32(data3.rbegin(), data3.rend());
CHECK_EQUAL(compare2, hash3);
}
//*************************************************************************
TEST(test_jenkins_64_constructor)
{
std::string data("123456789");
uint64_t hash = etl::jenkins<uint64_t>(data.begin(), data.end());
uint64_t compare = jenkins64(data.begin(), data.end());
CHECK_EQUAL(compare, hash);
}
//*************************************************************************
TEST(test_jenkins_64_add_values)
{
std::string data("123456789");
etl::jenkins<uint64_t> jenkins_64_calculator;
for (size_t i = 0; i < data.size(); ++i)
{
jenkins_64_calculator.add(data[i]);
}
uint64_t hash = jenkins_64_calculator;
uint64_t compare = jenkins64(data.begin(), data.end());
CHECK_EQUAL(compare, hash);
}
//*************************************************************************
TEST(test_jenkins_64_add_range)
{
std::string data("123456789");
etl::jenkins<uint64_t> jenkins_64_calculator;
jenkins_64_calculator.add(data.begin(), data.end());
uint64_t hash = jenkins_64_calculator.value();
uint64_t compare = jenkins64(data.begin(), data.end());
CHECK_EQUAL(compare, hash);
}
//*************************************************************************
TEST(test_jenkins_64_add_range_endian)
{
std::vector<uint8_t> data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
std::vector<uint32_t> data2 = { 0x04030201, 0x08070605 };
std::vector<uint8_t> data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };
uint64_t hash1 = etl::jenkins<uint64_t>(data1.begin(), data1.end());
uint64_t hash2 = etl::jenkins<uint64_t>((uint8_t*)&data2[0], (uint8_t*)&data2[0] + (data2.size() * sizeof(uint32_t)));
uint64_t hash3 = etl::jenkins<uint64_t>(data3.rbegin(), data3.rend());
CHECK_EQUAL(hash1, hash2);
CHECK_EQUAL(hash1, hash3);
uint64_t compare1 = jenkins64(data1.begin(), data1.end());
CHECK_EQUAL(compare1, hash1);
uint64_t compare2 = jenkins64((uint8_t*)&data2[0], (uint8_t*)&data2[0] + (data2.size() * sizeof(uint32_t)));
CHECK_EQUAL(compare2, hash2);
uint64_t compare3 = jenkins64(data3.rbegin(), data3.rend());
CHECK_EQUAL(compare2, hash3);
}
};
}

View File

@ -126,7 +126,7 @@ namespace
//*************************************************************************
TEST(test_power)
{
int actual;
uint64_t actual;
// 2^1
actual = etl::power<2, 1>::value;
@ -163,6 +163,18 @@ namespace
// 10^9
actual = etl::power<10, 9>::value;
CHECK_EQUAL(1000000000, actual);
// 2^16
actual = etl::power<2, 15>::value;
CHECK_EQUAL(0x8000, actual);
// 2^31
actual = etl::power<2, 31>::value;
CHECK_EQUAL(0x80000000, actual);
// 2^63
actual = etl::power<2, 63>::value;
CHECK_EQUAL(0x8000000000000000, actual);
}
//*************************************************************************

115
test/test_murmur3.cpp Normal file
View File

@ -0,0 +1,115 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
Copyright(c) 2014 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include <UnitTest++/UnitTest++.h>
#include "murmurhash3.h" // The 'C' reference implementation.
#include <iterator>
#include <string>
#include <vector>
#include <stdint.h>
#include "../murmur3.h"
#include "../endian.h"
namespace
{
SUITE(test_murmur3)
{
//*************************************************************************
TEST(test_murmur3_32_constructor)
{
std::string data("123456789");
uint32_t hash = etl::murmur3<uint32_t>(data.begin(), data.end());
uint32_t compare;
MurmurHash3_x86_32(data.c_str(), data.size(), 0, &compare);
CHECK_EQUAL(compare, hash);
}
//*************************************************************************
TEST(test_murmur3_32_add_values)
{
std::string data("123456789");
etl::murmur3<uint32_t> murmur3_32_calculator;
for (size_t i = 0; i < data.size(); ++i)
{
murmur3_32_calculator.add(data[i]);
}
uint32_t hash = murmur3_32_calculator;
uint32_t compare;
MurmurHash3_x86_32(data.c_str(), data.size(), 0, &compare);
CHECK_EQUAL(compare, hash);
}
//*************************************************************************
TEST(test_murmur3_32_add_range)
{
std::string data("123456789");
etl::murmur3<uint32_t> murmur3_32_calculator;
murmur3_32_calculator.add(data.begin(), data.end());
uint32_t hash = murmur3_32_calculator.value();
uint32_t compare;
MurmurHash3_x86_32(data.c_str(), data.size(), 0, &compare);
CHECK_EQUAL(compare, hash);
}
//*************************************************************************
TEST(test_murmur3_32_add_range_endian)
{
std::vector<uint8_t> data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
std::vector<uint32_t> data2 = { 0x04030201, 0x08070605 };
uint32_t hash1 = etl::murmur3<uint32_t>(data1.begin(), data1.end());
uint32_t hash2 = etl::murmur3<uint32_t>((uint8_t*)&data2[0], (uint8_t*)&data2[0] + (data2.size() * sizeof(uint32_t)));
CHECK_EQUAL(hash1, hash2);
uint32_t compare1;
MurmurHash3_x86_32(&*data1.begin(), data1.size(), 0, &compare1);
CHECK_EQUAL(compare1, hash1);
uint32_t compare2;
MurmurHash3_x86_32((uint8_t*)&data2[0], data2.size() * sizeof(uint32_t), 0, &compare2);
CHECK_EQUAL(compare2, hash2);
}
};
}

View File

@ -174,19 +174,23 @@ namespace
//*************************************************************************
TEST(test_optional_container)
{
// The indexed access doesn't work in Linux for some reason!!!
#ifndef PLATFORM_LINUX
etl::optional<etl::vector<Data, 10>> container;
CHECK(!bool(container));
CHECK(!bool(container));//
container = etl::vector<Data, 10>();
CHECK(bool(container));
container.value().resize(5, Data("1"));
CHECK_EQUAL(5, container.value().size());
CHECK_EQUAL(Data("1"), container.value()[0]);
CHECK_EQUAL(Data("1"), container.value()[1]);
CHECK_EQUAL(Data("1"), container.value()[2]);
CHECK_EQUAL(Data("1"), container.value()[3]);
CHECK_EQUAL(Data("1"), container.value()[4]);
#endif
}
//*************************************************************************
@ -196,5 +200,45 @@ namespace
CHECK_THROW(Data d(data1.value()), etl::optional_invalid);
}
//*************************************************************************
TEST(test_swap)
{
etl::optional<Data> original1(Data("1"));
etl::optional<Data> original2(Data("2"));
etl::optional<Data> data1;
etl::optional<Data> data2;
// Both invalid.
swap(data1, data2);
CHECK(!bool(data1));
CHECK(!bool(data2));
// Data1 valid;
data1 = original1;
data2 = etl::nullopt;
swap(data1, data2);
CHECK(!bool(data1));
CHECK(bool(data2));
CHECK_EQUAL(data2, original1);
// Data2 valid;
data1 = etl::nullopt;
data2 = original2;
swap(data1, data2);
CHECK(bool(data1));
CHECK(!bool(data2));
CHECK_EQUAL(data1, original2);
// Both valid;
data1 = original1;
data2 = original2;
swap(data1, data2);
CHECK(bool(data1));
CHECK(bool(data2));
CHECK_EQUAL(data1, original2);
CHECK_EQUAL(data2, original1);
}
};
}

152
test/test_pearson.cpp Normal file
View File

@ -0,0 +1,152 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
Copyright(c) 2015 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include <UnitTest++/UnitTest++.h>
#include <iterator>
#include <string>
#include <vector>
#include <iomanip>
#include <stdint.h>
#include "../pearson.h"
#include "../endian.h"
const size_t HASH_SIZE = 8;
typedef etl::pearson<HASH_SIZE>::value_type hash_t;
//***************************************************************************
/// Pearson lookup table
/// \ingroup pearson
//***************************************************************************
namespace etl
{
extern const uint8_t PEARSON_LOOKUP[];
}
//***************************************************************************
// Comparison calculator based on Wikipedia example. https://en.wikipedia.org/wiki/Pearson_hashing
//***************************************************************************
template <typename TContainer>
hash_t Pearson_Compare(const TContainer& data)
{
hash_t hash;
hash.fill(0);
for (size_t j = 0; j < HASH_SIZE; ++j)
{
uint8_t subhash = etl::PEARSON_LOOKUP[(data[0] + j) % 256];
for (size_t i = 1; i < data.size(); ++i)
{
subhash = etl::PEARSON_LOOKUP[subhash ^ data[i]];
}
hash[j] = subhash;
}
return hash;
}
//***************************************************************************
// Output stream for hash_t
//***************************************************************************
std::ostream& operator <<(std::ostream& os, const hash_t& hash)
{
for (size_t i = 0; i < hash.size(); ++i)
{
os << int(hash[i]) << " ";
}
return os;
}
namespace
{
SUITE(test_pearson)
{
//*************************************************************************
TEST(test_pearson_constructor)
{
std::string data("123456789");
hash_t compare = Pearson_Compare(data);
hash_t hash = etl::pearson<HASH_SIZE>(data.begin(), data.end());
CHECK_EQUAL(compare, hash);
}
//*************************************************************************
TEST(test_pearson_add_values)
{
std::string data("123456789");
etl::pearson<HASH_SIZE> pearson_calculator;
for (size_t i = 0; i < data.size(); ++i)
{
pearson_calculator.add(data[i]);
}
hash_t compare = Pearson_Compare(data);
hash_t hash = pearson_calculator;
CHECK_EQUAL(compare, hash);
}
//*************************************************************************
TEST(test_pearson_add_range)
{
std::string data("123456789");
etl::pearson<HASH_SIZE> pearson_calculator;
pearson_calculator.add(data.begin(), data.end());
hash_t compare = Pearson_Compare(data);
hash_t hash = pearson_calculator.value();
CHECK_EQUAL(compare, hash);
}
//*************************************************************************
TEST(test_pearson_add_range_endian)
{
std::vector<uint8_t> data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
std::vector<uint32_t> data2 = { 0x04030201, 0x08070605 };
std::vector<uint8_t> data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };
hash_t hash1 = etl::pearson<HASH_SIZE>(data1.begin(), data1.end());
hash_t hash2 = etl::pearson<HASH_SIZE>((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size()));
CHECK_EQUAL(hash1, hash2);
hash_t hash3 = etl::pearson<HASH_SIZE>(data3.rbegin(), data3.rend());
CHECK_EQUAL(hash1, hash3);
}
};
}

View File

@ -242,5 +242,43 @@ namespace
CHECK_EQUAL(*i_compare++, *i_test++);
}
}
////*************************************************************************
//TEST(test_get_iterator)
//{
// typedef etl::pool<Test_Data, 4> Pool;
// Pool pool;
// Test_Data not_in_pool;
// Test_Data* p1 = pool.allocate();
// Test_Data* p2 = pool.allocate();
// Pool::iterator i_data = pool.get_iterator(*p1);
// Pool::iterator i_ndata = pool.get_iterator(not_in_pool);
// CHECK(p1 == &*i_data);
// CHECK(p2 != &*i_data);
// CHECK(pool.end() == i_ndata);
//}
////*************************************************************************
//TEST(test_get_iterator_const)
//{
// typedef etl::pool<Test_Data, 4> Pool;
// Pool pool;
// const Test_Data not_in_pool;
// const Test_Data* p1 = pool.allocate();
// const Test_Data* p2 = pool.allocate();
// Pool::const_iterator i_data = pool.get_iterator(*p1);
// Pool::const_iterator i_ndata = pool.get_iterator(not_in_pool);
// CHECK(p1 == &*i_data);
// CHECK(p2 != &*i_data);
// CHECK(pool.end() == i_ndata);
//}
};
}

View File

@ -106,64 +106,64 @@ namespace
std::vector<int> excess_data;
std::vector<int> different_data;
std::vector<int> random_data;
SetupFixture()
{
int n[] =
{
{ 0 },
{ 1 },
{ 2 },
{ 3 },
{ 4 },
{ 5 },
{ 6 },
{ 7 },
{ 8 },
{ 9 },
};
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
};
Data::value_type n2[] =
{
{ 0 },
{ 1 },
{ 2 },
{ 3 },
{ 4 },
{ 5 },
{ 6 },
{ 7 },
{ 8 },
{ 9 },
{ 10 },
};
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
};
int n3[] =
{
{ 10 },
{ 11 },
{ 12 },
{ 13 },
{ 14 },
{ 15 },
{ 16 },
{ 17 },
{ 18 },
{ 19 },
};
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
};
int n4[] =
{
{ 6 },
{ 5 },
{ 0 },
{ 8 },
{ 9 },
{ 2 },
{ 1 },
{ 3 },
{ 7 },
{ 4 },
6,
5,
0,
8,
9,
2,
1,
3,
7,
4,
};
initial_data.assign(std::begin(n), std::end(n));

View File

@ -239,10 +239,10 @@ namespace
TEST(test_add_reference)
{
CHECK((std::is_same<etl::add_reference<int>::type, std::add_lvalue_reference<int>::type>::value));
CHECK((std::is_same<etl::add_reference<int&>::type, std::add_reference<int&>::type>::value));
CHECK((std::is_same<etl::add_reference<const int&>::type, std::add_reference<const int&>::type>::value));
CHECK((std::is_same<etl::add_reference<volatile int&>::type, std::add_reference<volatile int&>::type>::value));
CHECK((std::is_same<etl::add_reference<const volatile int&>::type, std::add_reference<const volatile int&>::type>::value));
CHECK((std::is_same<etl::add_reference<int&>::type, std::add_lvalue_reference<int&>::type>::value));
CHECK((std::is_same<etl::add_reference<const int&>::type, std::add_lvalue_reference<const int&>::type>::value));
CHECK((std::is_same<etl::add_reference<volatile int&>::type, std::add_lvalue_reference<volatile int&>::type>::value));
CHECK((std::is_same<etl::add_reference<const volatile int&>::type, std::add_lvalue_reference<const volatile int&>::type>::value));
}

View File

@ -49,7 +49,7 @@ struct base
struct not_base
{
not_base()
: value(0)
: value(0)
{
}
@ -83,7 +83,7 @@ typedef etl::variant<char, unsigned char, short, unsigned short, int, unsigned i
test_variant_max_types variant_max;
namespace
{
{
SUITE(test_variant)
{
TEST(test_alignment)
@ -93,10 +93,15 @@ namespace
typedef etl::variant<char, int> test_variant_c;
typedef etl::variant<char, double> test_variant_d;
CHECK_EQUAL(int(etl::alignment_of<char>::value), int(etl::alignment_of<test_variant_a>::value));
CHECK_EQUAL(int(etl::alignment_of<short>::value), int(etl::alignment_of<test_variant_b>::value));
CHECK_EQUAL(int(etl::alignment_of<int>::value), int(etl::alignment_of<test_variant_c>::value));
CHECK_EQUAL(int(etl::alignment_of<double>::value), int(etl::alignment_of<test_variant_d>::value));
static test_variant_a a(char('1'));
static test_variant_b b(short(2));
static test_variant_c c(3);
static test_variant_d d(4.5);
CHECK((uintptr_t(&a.get<char>()) % uintptr_t(etl::alignment_of<char>::value)) == 0);
CHECK((uintptr_t(&b.get<short>()) % uintptr_t(etl::alignment_of<short>::value)) == 0);
CHECK((uintptr_t(&c.get<int>()) % uintptr_t(etl::alignment_of<int>::value)) == 0);
CHECK((uintptr_t(&d.get<double>()) % uintptr_t(etl::alignment_of<double>::value)) == 0);
}
//*************************************************************************
@ -178,7 +183,7 @@ namespace
std::string text("Some Text");
test_variant_1 variant;
variant = text;
CHECK_THROW(int i = variant, etl::variant_incorrect_type_exception);
}
@ -198,7 +203,7 @@ namespace
variant_2 = text;
CHECK(!variant_1.is_same_type(variant_2));
}
}
//*************************************************************************
TEST(test_is_same_type_different_variants)
@ -215,8 +220,8 @@ namespace
variant_2 = 3.3;
CHECK(!variant_1.is_same_type(variant_2));
}
}
//*************************************************************************
TEST(Testis_supported_type)
{
@ -271,7 +276,7 @@ namespace
{
test_variant_1 variant;
variant = 1;
CHECK_THROW(char c =variant.get<char>(), etl::variant_exception);
}
@ -326,7 +331,7 @@ namespace
s = s_;
}
char c;
char c;
std::string s;
int i;
};
@ -429,4 +434,4 @@ namespace
CHECK_EQUAL(2, variant.get<derived_2>().value);
}
};
}
}

View File

@ -849,5 +849,22 @@ namespace
const Data initial2(initial_data.begin(), initial_data.end());
CHECK((initial >= initial2) == (initial_data >= initial_data));
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_allocated_size)
{
const size_t INITIAL_SIZE = 5;
Data data(INITIAL_SIZE);
size_t a = sizeof(Data);
size_t b = SIZE * sizeof(int);
size_t c = sizeof(etl::vector_base);
size_t d = sizeof(etl::ivector<int>);
size_t expected_size = (SIZE * sizeof(int)) + (2 * sizeof(size_t)) + sizeof(int*);
CHECK_EQUAL(expected_size, sizeof(Data));
}
};
}

View File

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Express 2013 for Windows Desktop
VisualStudioVersion = 12.0.21005.1
# Visual Studio 14
VisualStudioVersion = 14.0.23107.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "etl", "etl.vcxproj", "{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}"
EndProject

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@ -20,13 +20,13 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
@ -82,6 +82,9 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<PostBuildEvent>
<Command>$(OutDir)\etl.exe</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\..\unittest-cpp\UnitTest++\AssertException.h" />
@ -119,6 +122,7 @@
<ClInclude Include="..\..\binary.h" />
<ClInclude Include="..\..\bitset.h" />
<ClInclude Include="..\..\bloom_filter.h" />
<ClInclude Include="..\..\bsd_checksum.h" />
<ClInclude Include="..\..\checksum.h" />
<ClInclude Include="..\..\crc16.h" />
<ClInclude Include="..\..\crc16_ccitt.h" />
@ -137,6 +141,10 @@
<ClInclude Include="..\..\factorial.h" />
<ClInclude Include="..\..\fibonacci.h" />
<ClInclude Include="..\..\fixed_iterator.h" />
<ClInclude Include="..\..\flat_multimap.h" />
<ClInclude Include="..\..\flat_multimap_base.h" />
<ClInclude Include="..\..\flat_multiset.h" />
<ClInclude Include="..\..\flat_multiset_base.h" />
<ClInclude Include="..\..\flat_set.h" />
<ClInclude Include="..\..\flat_set_base.h" />
<ClInclude Include="..\..\fnv_1.h" />
@ -147,40 +155,51 @@
<ClInclude Include="..\..\hash.h" />
<ClInclude Include="..\..\ibitset.h" />
<ClInclude Include="..\..\ideque.h" />
<ClInclude Include="..\..\iflat_multimap.h" />
<ClInclude Include="..\..\iflat_multiset.h" />
<ClInclude Include="..\..\iflat_set.h" />
<ClInclude Include="..\..\iforward_list.h" />
<ClInclude Include="..\..\ihash.h" />
<ClInclude Include="..\..\ilist.h" />
<ClInclude Include="..\..\iflat_map.h" />
<ClInclude Include="..\..\ilru_cache.h" />
<ClInclude Include="..\..\imap.h" />
<ClInclude Include="..\..\imru_cache.h" />
<ClInclude Include="..\..\imultimap.h" />
<ClInclude Include="..\..\imultiset.h" />
<ClInclude Include="..\..\instance_count.h" />
<ClInclude Include="..\..\integral_limits.h" />
<ClInclude Include="..\..\intrusive_forward_list.h" />
<ClInclude Include="..\..\io_port.h" />
<ClInclude Include="..\..\ipool.h" />
<ClInclude Include="..\..\ipriority_queue.h" />
<ClInclude Include="..\..\iqueue.h" />
<ClInclude Include="..\..\irr_cache.h" />
<ClInclude Include="..\..\iset.h" />
<ClInclude Include="..\..\istack.h" />
<ClInclude Include="..\..\container.h" />
<ClInclude Include="..\..\iunordered_map.h" />
<ClInclude Include="..\..\ivector.h" />
<ClInclude Include="..\..\jenkins.h" />
<ClInclude Include="..\..\largest.h" />
<ClInclude Include="..\..\list.h" />
<ClInclude Include="..\..\list_base.h" />
<ClInclude Include="..\..\log.h" />
<ClInclude Include="..\..\flat_map.h" />
<ClInclude Include="..\..\flat_map_base.h" />
<ClInclude Include="..\..\lru_cache.h" />
<ClInclude Include="..\..\map.h" />
<ClInclude Include="..\..\map_base.h" />
<ClInclude Include="..\..\mru_cache.h" />
<ClInclude Include="..\..\multimap.h" />
<ClInclude Include="..\..\multiset.h" />
<ClInclude Include="..\..\murmur3.h" />
<ClInclude Include="..\..\nullptr.h" />
<ClInclude Include="..\..\numeric.h" />
<ClInclude Include="..\..\observer.h" />
<ClInclude Include="..\..\optional.h" />
<ClInclude Include="..\..\parameter_type.h" />
<ClInclude Include="..\..\pearson.h" />
<ClInclude Include="..\..\pool.h" />
<ClInclude Include="..\..\pool_base.h" />
<ClInclude Include="..\..\power.h" />
@ -189,6 +208,7 @@
<ClInclude Include="..\..\queue.h" />
<ClInclude Include="..\..\queue_base.h" />
<ClInclude Include="..\..\radix.h" />
<ClInclude Include="..\..\rr_cache.h" />
<ClInclude Include="..\..\set.h" />
<ClInclude Include="..\..\set_base.h" />
<ClInclude Include="..\..\smallest.h" />
@ -204,6 +224,7 @@
<ClInclude Include="..\..\visitor.h" />
<ClInclude Include="..\data.h" />
<ClInclude Include="..\ExtraCheckMacros.h" />
<ClInclude Include="..\murmurhash3.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\unittest-cpp\UnitTest++\AssertException.cpp" />
@ -231,17 +252,19 @@
<ClCompile Include="..\..\crc64_ecma.cpp" />
<ClCompile Include="..\..\crc8_ccitt.cpp" />
<ClCompile Include="..\..\error_handler.cpp" />
<ClCompile Include="..\..\pearson.cpp" />
<ClCompile Include="..\main.cpp" />
<ClCompile Include="..\murmurhash3.cpp" />
<ClCompile Include="..\test_algorithm.cpp" />
<ClCompile Include="..\test_alignment.cpp" />
<ClCompile Include="..\test_array.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../../unittest-cpp</AdditionalIncludeDirectories>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\test_binary.cpp" />
<ClCompile Include="..\test_bitset.cpp" />
<ClCompile Include="..\test_bloom_filter.cpp" />
<ClCompile Include="..\test_bsd_checksum.cpp" />
<ClCompile Include="..\test_checksum.cpp" />
<ClCompile Include="..\test_container.cpp" />
<ClCompile Include="..\test_crc.cpp" />
@ -255,6 +278,8 @@
<ClCompile Include="..\test_error_handler.cpp" />
<ClCompile Include="..\test_exception.cpp" />
<ClCompile Include="..\test_fixed_iterator.cpp" />
<ClCompile Include="..\test_flat_multimap.cpp" />
<ClCompile Include="..\test_flat_multiset.cpp" />
<ClCompile Include="..\test_flat_set.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
</ClCompile>
@ -266,6 +291,7 @@
<ClCompile Include="..\test_instance_count.cpp" />
<ClCompile Include="..\test_integral_limits.cpp" />
<ClCompile Include="..\test_io_port.cpp" />
<ClCompile Include="..\test_jenkins.cpp" />
<ClCompile Include="..\test_largest.cpp" />
<ClCompile Include="..\test_list.cpp" />
<ClCompile Include="..\test_flat_map.cpp">
@ -275,11 +301,13 @@
<ClCompile Include="..\test_maths.cpp" />
<ClCompile Include="..\test_multimap.cpp" />
<ClCompile Include="..\test_multiset.cpp" />
<ClCompile Include="..\test_murmur3.cpp" />
<ClCompile Include="..\test_numeric.cpp" />
<ClCompile Include="..\test_observer.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\test_optional.cpp" />
<ClCompile Include="..\test_pearson.cpp" />
<ClCompile Include="..\test_pool.cpp" />
<ClCompile Include="..\test_priority_queue.cpp" />
<ClCompile Include="..\test_queue.cpp" />
@ -287,9 +315,6 @@
<ClCompile Include="..\test_smallest.cpp" />
<ClCompile Include="..\test_stack.cpp" />
<ClCompile Include="..\test_type_traits.cpp" />
<ClCompile Include="..\test_unordered_map.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\test_variant.cpp" />
<ClCompile Include="..\test_vector.cpp" />
<ClCompile Include="..\test_visitor.cpp" />

View File

@ -396,6 +396,60 @@
<ClInclude Include="..\..\priority_queue_base.h">
<Filter>ETL\Containers</Filter>
</ClInclude>
<ClInclude Include="..\..\ilru_cache.h">
<Filter>ETL\Maths</Filter>
</ClInclude>
<ClInclude Include="..\..\imru_cache.h">
<Filter>ETL\Maths</Filter>
</ClInclude>
<ClInclude Include="..\..\irr_cache.h">
<Filter>ETL\Maths</Filter>
</ClInclude>
<ClInclude Include="..\..\jenkins.h">
<Filter>ETL\Maths</Filter>
</ClInclude>
<ClInclude Include="..\..\lru_cache.h">
<Filter>ETL\Maths</Filter>
</ClInclude>
<ClInclude Include="..\..\mru_cache.h">
<Filter>ETL\Maths</Filter>
</ClInclude>
<ClInclude Include="..\..\murmur3.h">
<Filter>ETL\Maths</Filter>
</ClInclude>
<ClInclude Include="..\..\rr_cache.h">
<Filter>ETL\Maths</Filter>
</ClInclude>
<ClInclude Include="..\murmurhash3.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\..\pearson.h">
<Filter>ETL\Maths</Filter>
</ClInclude>
<ClInclude Include="..\..\bsd_checksum.h">
<Filter>ETL\Maths</Filter>
</ClInclude>
<ClInclude Include="..\..\flat_multimap.h">
<Filter>ETL\Containers</Filter>
</ClInclude>
<ClInclude Include="..\..\flat_multimap_base.h">
<Filter>ETL\Containers</Filter>
</ClInclude>
<ClInclude Include="..\..\flat_multiset.h">
<Filter>ETL\Containers</Filter>
</ClInclude>
<ClInclude Include="..\..\flat_multiset_base.h">
<Filter>ETL\Containers</Filter>
</ClInclude>
<ClInclude Include="..\..\iflat_multiset.h">
<Filter>ETL\Containers</Filter>
</ClInclude>
<ClInclude Include="..\..\iflat_multimap.h">
<Filter>ETL\Containers</Filter>
</ClInclude>
<ClInclude Include="..\..\intrusive_forward_list.h">
<Filter>ETL\Containers</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\unittest-cpp\UnitTest++\AssertException.cpp">
@ -596,9 +650,6 @@
<ClCompile Include="..\test_io_port.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\test_unordered_map.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\test_optional.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -614,6 +665,30 @@
<ClCompile Include="..\test_priority_queue.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\test_flat_multimap.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\test_jenkins.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\test_murmur3.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\murmurhash3.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\test_flat_multiset.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\pearson.cpp">
<Filter>ETL\Maths</Filter>
</ClCompile>
<ClCompile Include="..\test_pearson.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\test_bsd_checksum.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\..\Doxyfile">

291419
test/words.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -209,7 +209,7 @@ namespace etl
///\ingroup type_traits
template <typename T> struct is_fundamental : integral_constant<bool, is_arithmetic<T>::value ||
is_void<T>::value ||
is_same<nullptr_t,
is_same<std::nullptr_t,
typename remove_cv<T>::type>::value> {};
/// is_compound
@ -232,14 +232,22 @@ namespace etl
template <typename T> struct is_reference : false_type {};
template <typename T> struct is_reference<T&> : true_type {};
/// conditional
///\ingroup type_traits
template <bool B, typename T, typename F> struct conditional { typedef T type; };
template <typename T, typename F> struct conditional<false, T, F> { typedef F type; };
/// make_signed
///\ingroup type_traits
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; };
#ifdef COMPILER_MICROSOFT
template <> struct make_signed<wchar_t> { typedef short type; };
#endif
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;
};
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; };
@ -254,9 +262,12 @@ 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; };
#ifdef COMPILER_MICROSOFT
template <> struct make_unsigned<wchar_t> { typedef unsigned short type; };
#endif
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;
};
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; };
@ -269,11 +280,6 @@ namespace etl
template <bool B, typename T = void> struct enable_if {};
template <typename T> struct enable_if<true, T> { typedef T type; };
/// conditional
///\ingroup type_traits
template <bool B, typename T, typename F> struct conditional { typedef T type; };
template <typename T, typename F> struct conditional<false, T, F> { typedef F type; };
/// extent
///\ingroup type_traits
template <typename T, size_t N = 0>
@ -330,7 +336,7 @@ namespace etl
#ifdef COMPILER_GCC
template <typename T> struct alignment_of : integral_constant<size_t, size_t(__alignof__(T))> {};
#endif
#ifdef COMPILER_KEIL
template <typename T> struct alignment_of : integral_constant<size_t, size_t(__alignof__(T))> {};
#endif