Merge branch 'development' into feature/#596-helper-functions-to-convert-strings-to-numeric-values

# Conflicts:
#	include/etl/file_error_numbers.h
This commit is contained in:
John Wellbelove 2022-10-07 12:52:58 +01:00
commit 8cd0546e36
37 changed files with 1582 additions and 602 deletions

23
.gitignore vendored
View File

@ -3,6 +3,8 @@
## Personal
#################
docs/html
include/etl/html/
include/etl/latex/
test/vs2013/Debug
test/vs2013/Release
test/keil/Debug
@ -91,14 +93,12 @@ build/
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual C++ cache files
@ -219,7 +219,6 @@ $RECYCLE.BIN/
*.egg
*.egg-info
dist/
build/
eggs/
parts/
var/
@ -241,7 +240,6 @@ pip-log.txt
#Mr Developer
.mr.developer.cfg
*.depend
*.depend
*.layout
*.session
*.tags
@ -270,13 +268,9 @@ test/kdevelopbuild/unittest++
test/random_clcg.csv
test/random_hash.csv
test/random_lcg.csv
test/random_lcg.csv
test/random_lcg.csv
test/random_lsfr.csv
test/random_lsfr.csv
test/random_mwc.csv
test/random_pcg.csv
test/random_pcg.csv
test/random_xorshift.csv
test/cmake_install.cmake
test/Makefile
@ -331,21 +325,16 @@ test/vs2019/Test2
test/vs2019/Debug MSVC - Force C++03
test/vs2019/Debug LLVM - No STL
test/vs2019/Debug - No STL
test/meson-info
test/etl_unit_tests.p
test/meson-logs
test/meson-private
test/.ninja_deps
test/.ninja_log
test/build.ninja
test/compile_commands.json
test/etl_unit_tests
test/build-make
test/build-make
test/meson-info
test/meson-logs
test/meson-private
test/build-make
test/build-ninja
test/vs2019/Debug MSVC C++20
test/vs2019/Debug MSVC C++20 - No STL
@ -370,14 +359,6 @@ test/etl_error_handler/build-log_errors-GCC-Debug
test/etl_error_handler/build-exceptions_and_log_errors-GCC-Debug
test/etl_error_handler/build-exceptions-GCC-Debug
test/etl_error_handler/exceptions_and_log_errors/.vs
test/etl_error_handler/exceptions/build-make
test/etl_error_handler/log_errors/build-make
test/etl_error_handler/log_errors_and_exceptions/build-make
test/etl_error_handler/log_errors_and_exceptions/.vs
test/etl_error_handler/exceptions/build-make
test/etl_error_handler/log_errors/build-make
test/etl_error_handler/log_errors_and_exceptions/.vs
test/etl_error_handler/log_errors_and_exceptions/build-make
examples/ArmTimerCallbacks - C++/ArmTimerCallbacks.uvoptx
test/vs2022/.vs
test/vs2022/random_clcg.csv

View File

@ -872,7 +872,7 @@ EXCLUDE_SYMBOLS =
# that contain example code fragments that are included (see the \include
# command).
EXAMPLE_PATH =
EXAMPLE_PATH = ./test
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and

View File

@ -99,5 +99,6 @@ SOFTWARE.
#define ETL_BYTE_STREAM_FILE_ID "66"
#define ETL_BIP_BUFFER_SPSC_ATOMIC_FILE_ID "67"
#define ETL_TO_ARITHMETIC_FILE_ID "68"
#define ETL_REFERENCE_COUNTED_OBJECT_FILE_ID "69"
#endif

View File

@ -91,7 +91,7 @@ namespace etl
/// Primary definition of base hash class, by default is poisoned
//*************************************************************************
template<typename T, bool IsEnum=false>
struct hash_base
struct hash_base
{
private:
hash_base(); // Can't default construct
@ -363,6 +363,10 @@ namespace etl
float v;
} u;
if (v == -0.0f)
{ // -0.0 and 0.0 are represented differently at bit level
v = 0.0f;
}
u.v = v;
return u.s;
@ -393,6 +397,10 @@ namespace etl
double v;
} u;
if (v == -0.0)
{ // -0.0 and 0.0 are represented differently at bit level
v = 0.0;
}
u.v = v;
return u.s;
@ -423,6 +431,10 @@ namespace etl
long double v;
} u;
if (v == -0.0L)
{ // -0.0 and 0.0 are represented differently at bit level
v = 0.0L;
}
u.v = v;
return u.s;
@ -465,7 +477,7 @@ namespace etl
}
};
namespace private_hash
namespace private_hash
{
//*************************************************************************
/// Specialization for enums
@ -475,11 +487,11 @@ namespace etl
{
size_t operator()(T v) const
{
if (sizeof(size_t) >= sizeof(T))
if (sizeof(size_t) >= sizeof(T))
{
return static_cast<size_t>(v);
}
else
}
else
{
return ::etl::hash<unsigned long long>()(static_cast<unsigned long long>(v));
}

View File

@ -34,6 +34,7 @@ SOFTWARE.
#include "platform.h"
#include "type_traits.h"
#include "utility.h"
#include "private/addressof.h"
#if ETL_USING_STL || defined(ETL_IN_UNIT_TEST)
#include <iterator>
@ -91,10 +92,8 @@ namespace etl
//***************************************************************************
// advance
#if ETL_NOT_USING_STL
template <typename TIterator, typename TDistance>
ETL_CONSTEXPR17 void advance_helper(TIterator& itr, TDistance n, ETL_OR_STD::output_iterator_tag)
ETL_CONSTEXPR14 void advance_helper(TIterator& itr, TDistance n, ETL_OR_STD::output_iterator_tag)
{
while (n--)
{
@ -103,7 +102,7 @@ namespace etl
}
template <typename TIterator, typename TDistance>
ETL_CONSTEXPR17 void advance_helper(TIterator& itr, TDistance n, ETL_OR_STD::forward_iterator_tag)
ETL_CONSTEXPR14 void advance_helper(TIterator& itr, TDistance n, ETL_OR_STD::forward_iterator_tag)
{
while (n--)
{
@ -112,7 +111,7 @@ namespace etl
}
template <typename TIterator, typename TDistance>
ETL_CONSTEXPR17 void advance_helper(TIterator& itr, TDistance n, ETL_OR_STD::bidirectional_iterator_tag)
ETL_CONSTEXPR14 void advance_helper(TIterator& itr, TDistance n, ETL_OR_STD::bidirectional_iterator_tag)
{
if (n > 0)
{
@ -131,34 +130,23 @@ namespace etl
}
template <typename TIterator, typename TDistance>
ETL_CONSTEXPR17 void advance_helper(TIterator& itr, TDistance n, ETL_OR_STD::random_access_iterator_tag)
ETL_CONSTEXPR14 void advance_helper(TIterator& itr, TDistance n, ETL_OR_STD::random_access_iterator_tag)
{
itr += n;
}
template <typename TIterator, typename TDistance>
ETL_CONSTEXPR17 void advance(TIterator& itr, TDistance n)
ETL_CONSTEXPR14 void advance(TIterator& itr, TDistance n)
{
typedef typename etl::iterator_traits<TIterator>::iterator_category tag;
advance_helper(itr, n, tag());
}
#else
template <typename TIterator, typename TDistance>
ETL_CONSTEXPR17 void advance(TIterator& itr, TDistance n)
{
std::advance(itr, n);
}
#endif
//***************************************************************************
// distance
#if ETL_NOT_USING_STL
template<typename TIterator>
ETL_CONSTEXPR17 typename etl::iterator_traits<TIterator>::difference_type distance_helper(TIterator first, TIterator last, ETL_OR_STD::input_iterator_tag)
ETL_CONSTEXPR14 typename etl::iterator_traits<TIterator>::difference_type distance_helper(TIterator first, TIterator last, ETL_OR_STD::input_iterator_tag)
{
typename etl::iterator_traits<TIterator>::difference_type d = 0;
@ -172,7 +160,7 @@ namespace etl
}
template<typename TIterator>
ETL_CONSTEXPR17 typename etl::iterator_traits<TIterator>::difference_type distance_helper(TIterator first, TIterator last, ETL_OR_STD::forward_iterator_tag)
ETL_CONSTEXPR14 typename etl::iterator_traits<TIterator>::difference_type distance_helper(TIterator first, TIterator last, ETL_OR_STD::forward_iterator_tag)
{
typename etl::iterator_traits<TIterator>::difference_type d = 0;
@ -186,7 +174,7 @@ namespace etl
}
template<typename TIterator>
ETL_CONSTEXPR17 typename etl::iterator_traits<TIterator>::difference_type distance_helper(TIterator first, TIterator last, ETL_OR_STD::bidirectional_iterator_tag)
ETL_CONSTEXPR14 typename etl::iterator_traits<TIterator>::difference_type distance_helper(TIterator first, TIterator last, ETL_OR_STD::bidirectional_iterator_tag)
{
typename etl::iterator_traits<TIterator>::difference_type d = 0;
@ -200,52 +188,36 @@ namespace etl
}
template<typename TIterator>
ETL_CONSTEXPR17 typename etl::iterator_traits<TIterator>::difference_type distance_helper(TIterator first, TIterator last, ETL_OR_STD::random_access_iterator_tag)
ETL_CONSTEXPR14 typename etl::iterator_traits<TIterator>::difference_type distance_helper(TIterator first, TIterator last, ETL_OR_STD::random_access_iterator_tag)
{
return last - first;
}
template<typename TIterator>
ETL_CONSTEXPR17 typename etl::iterator_traits<TIterator>::difference_type distance(TIterator first, TIterator last)
ETL_CONSTEXPR14 typename etl::iterator_traits<TIterator>::difference_type distance(TIterator first, TIterator last)
{
typedef typename etl::iterator_traits<TIterator>::iterator_category tag;
return distance_helper(first, last, tag());
}
#else
template<typename TIterator>
ETL_CONSTEXPR17 typename std::iterator_traits<TIterator>::difference_type distance(TIterator first, TIterator last)
{
return std::distance(first, last);
}
#endif
//***************************************************************************
// Previous
template<typename TIterator>
ETL_CONSTEXPR17 TIterator prev(TIterator itr, typename etl::iterator_traits<TIterator>::difference_type n = 1)
ETL_CONSTEXPR14 TIterator prev(TIterator itr, typename etl::iterator_traits<TIterator>::difference_type n = 1)
{
#if ETL_NOT_USING_STL || ETL_CPP11_NOT_SUPPORTED
etl::advance(itr, -n);
#else
std::advance(itr, -n);
#endif
return itr;
}
//***************************************************************************
// Next
template<typename TIterator>
ETL_CONSTEXPR17 TIterator next(TIterator itr, typename etl::iterator_traits<TIterator>::difference_type n = 1)
ETL_CONSTEXPR14 TIterator next(TIterator itr, typename etl::iterator_traits<TIterator>::difference_type n = 1)
{
#if ETL_NOT_USING_STL || ETL_CPP11_NOT_SUPPORTED
etl::advance(itr, n);
#else
std::advance(itr, n);
#endif
return itr;
}
@ -281,7 +253,7 @@ namespace etl
}
template<class TOther>
ETL_CONSTEXPR14 reverse_iterator& operator=(const reverse_iterator<TOther>& other)
ETL_CONSTEXPR14 reverse_iterator& operator =(const reverse_iterator<TOther>& other)
{
current = other.base();
@ -371,49 +343,49 @@ namespace etl
TIterator current;
};
template <class TIterator>
template <typename TIterator>
ETL_CONSTEXPR14 bool operator ==(const reverse_iterator<TIterator>& lhs, const reverse_iterator<TIterator>& rhs)
{
return lhs.base() == rhs.base();
}
template <class TIterator>
template <typename TIterator>
ETL_CONSTEXPR14 bool operator !=(const reverse_iterator<TIterator>& lhs, const reverse_iterator<TIterator>& rhs)
{
return !(lhs == rhs);
}
template <class TIterator>
template <typename TIterator>
ETL_CONSTEXPR14 bool operator <(const reverse_iterator<TIterator>& lhs, const reverse_iterator<TIterator>& rhs)
{
return rhs.base() < lhs.base();
}
template <class TIterator>
template <typename TIterator>
ETL_CONSTEXPR14 bool operator >(const reverse_iterator<TIterator>& lhs, const reverse_iterator<TIterator>& rhs)
{
return rhs < lhs;
}
template <class TIterator>
template <typename TIterator>
ETL_CONSTEXPR14 bool operator <=(const reverse_iterator<TIterator>& lhs, const reverse_iterator<TIterator>& rhs)
{
return !(rhs < lhs);
}
template <class TIterator>
template <typename TIterator>
ETL_CONSTEXPR14 bool operator >=(const reverse_iterator<TIterator>& lhs, const reverse_iterator<TIterator>& rhs)
{
return !(lhs < rhs);
}
template <class TIterator>
template <typename TIterator>
ETL_CONSTEXPR14 typename reverse_iterator<TIterator>::difference_type operator -(const reverse_iterator<TIterator>& lhs, const reverse_iterator<TIterator>& rhs)
{
return rhs.base() - lhs.base();
}
template <class TIterator, class TDifference>
template <typename TIterator, class TDifference>
ETL_CONSTEXPR14 reverse_iterator<TIterator> operator +(TDifference n, const reverse_iterator<TIterator>& itr)
{
return itr.operator +(n);
@ -604,7 +576,226 @@ namespace etl
return etl::move_iterator<TIterator>(itr);
}
#endif
#endif //ETL_USING_CPP11
//***************************************************************************
// back_insert_iterator
//***************************************************************************
//***************************************************************************
///\brief Turns assignment into insertion.
///
/// These are output iterators, constructed from a container-of-T.
/// Assigning a T to the iterator appends it to the container using push_back.
///
/// @tparam TContainer
//***************************************************************************
template <typename TContainer>
class back_insert_iterator : public etl::iterator<ETL_OR_STD::output_iterator_tag, void, void, void, void>
{
public:
/// A nested typedef for the type of whatever container you used.
typedef TContainer container_type;
/// The only way to create this %iterator is with a container.
explicit ETL_CONSTEXPR14 back_insert_iterator(TContainer& c)
: container(etl::addressof(c))
{
}
//***************************************************************************
/// This kind of %iterator doesn't really have a @a position in the
/// container (you can think of the position as being permanently at
/// the end, if you like). Assigning a value to the %iterator will
/// always append the value to the end of the container.
///
/// @param value An instance of whatever type container_type::const_reference is;
/// presumably a reference-to-const T for container<T>.
/// @return This %iterator, for chained operations.
//***************************************************************************
ETL_CONSTEXPR14 back_insert_iterator& operator =(const typename TContainer::value_type& value)
{
container->push_back(value);
return (*this);
}
#if ETL_USING_CPP11
//***************************************************************************
/// Move assignment operator.
//***************************************************************************
ETL_CONSTEXPR14 back_insert_iterator& operator =(typename TContainer::value_type&& value)
{
container->push_back(etl::move(value));
return (*this);
}
#endif // ETL_USING_CPP11
//***************************************************************************
/// Dereference operator.
/// Simply returns *this.
//***************************************************************************
ETL_NODISCARD ETL_CONSTEXPR14 back_insert_iterator& operator *()
{
return (*this);
}
//***************************************************************************
/// Pre-increment operator.
/// Simply returns *this. (This %iterator does not @a move.)
//***************************************************************************
ETL_CONSTEXPR14 back_insert_iterator& operator ++()
{
return (*this);
}
//***************************************************************************
/// Post-increment operator.
/// Simply returns *this. (This %iterator does not @a move.)
//***************************************************************************
ETL_CONSTEXPR14 back_insert_iterator operator ++(int)
{
return (*this);
}
protected:
TContainer* container;
};
//***************************************************************************
/// This wrapper function helps in creating back_insert_iterator instances.
/// Typing the name of the %iterator requires knowing the precise full
/// type of the container, which can be tedious and impedes generic
/// programming. Using this function lets you take advantage of automatic
/// template parameter deduction, making the compiler match the correct types for you.
///
/// @tparam TContainer The container type.
/// @param container A container of arbitrary type.
/// @return An instance of back_insert_iterator working on @p container.
//***************************************************************************
template <typename TContainer>
ETL_NODISCARD
ETL_CONSTEXPR14
etl::back_insert_iterator<TContainer> back_inserter(TContainer& container)
{
return etl::back_insert_iterator<TContainer>(container);
}
//***************************************************************************
// front_insert_iterator
//***************************************************************************
//***************************************************************************
///\brief Turns assignment into insertion.
///
/// These are output iterators, constructed from a container-of-T.
/// Assigning a T to the iterator prepends it to the container using
/// push_front.
///
/// Tip: Using the front_inserter function to create these iterators can
/// save typing.
///
///\tparam TContainer The container type.
//***************************************************************************
template <typename TContainer>
class front_insert_iterator : public etl::iterator<ETL_OR_STD::output_iterator_tag, void, void, void, void>
{
public:
/// A nested typedef for the type of whatever container you used.
typedef TContainer container_type;
//***************************************************************************
/// Constructor
/// The only way to create this %iterator is with a container.
//***************************************************************************
explicit ETL_CONSTEXPR14 front_insert_iterator(TContainer& c)
: container(etl::addressof(c))
{
}
//***************************************************************************
/// This kind of %iterator doesn't really have a @a position in the
/// container (you can think of the position as being permanently at
/// the front, if you like). Assigning a value to the %iterator will
/// always prepend the value to the front of the container.
///
/// @param value An instance of whatever type
/// container_type::const_reference is; presumably a
/// reference-to-const T for container<T>.
/// @return This %iterator, for chained operations.
//***************************************************************************
ETL_CONSTEXPR14 front_insert_iterator& operator =(const typename TContainer::value_type& value)
{
container->push_front(value);
return (*this);
}
#if ETL_USING_CPP11
//***************************************************************************
/// Move assignment operator.
//***************************************************************************
ETL_CONSTEXPR14 front_insert_iterator& operator =(typename TContainer::value_type&& value)
{
container->push_front(etl::move(value));
return (*this);
}
#endif // ETL_USING_CPP11
//***************************************************************************
/// Dereference operator.
/// Simply returns *this.
//***************************************************************************
ETL_NODISCARD ETL_CONSTEXPR14 front_insert_iterator& operator *()
{
return (*this);
}
//***************************************************************************
/// Pre-increment operator.
/// Simply returns *this. (This %iterator does not @a move.)
//***************************************************************************
ETL_CONSTEXPR14 front_insert_iterator& operator ++()
{
return (*this);
}
//***************************************************************************
/// Post-increment operator.
/// Simply returns *this. (This %iterator does not @a move.)
//***************************************************************************
ETL_CONSTEXPR14 front_insert_iterator operator ++(int)
{
return (*this);
}
protected:
TContainer* container;
};
//***************************************************************************
/// This wrapper function helps in creating front_insert_iterator instances.
/// Typing the name of the %iterator requires knowing the precise full
/// type of the container, which can be tedious and impedes generic
/// programming. Using this function lets you take advantage of automatic
/// template parameter deduction, making the compiler match the correct
/// types for you.
///
///\tparam TContainer The container type.
///\param container A container of arbitrary type.
///\return An instance of front_insert_iterator working on @p x.
//***************************************************************************
template <typename TContainer>
ETL_NODISCARD
ETL_CONSTEXPR14
etl::front_insert_iterator<TContainer> front_inserter(TContainer& container)
{
return etl::front_insert_iterator<TContainer>(container);
}
//***************************************************************************
// Helper templates.

View File

@ -39,6 +39,7 @@ SOFTWARE.
#include "nullptr.h"
#include "alignment.h"
#include "placement_new.h"
#include "private/addressof.h"
#include <assert.h>
#include <string.h>
@ -52,21 +53,6 @@ SOFTWARE.
namespace etl
{
//*****************************************************************************
/// Gets the address of an object.
/// https://en.cppreference.com/w/cpp/memory/addressof
///\ingroup memory
//*****************************************************************************
template <typename T>
ETL_CONSTEXPR17 T* addressof(T& t)
{
#if ETL_USING_STL && ETL_USING_CPP11
return std::addressof(t);
#else
return reinterpret_cast<T*>(&const_cast<char&>(reinterpret_cast<const volatile char&>(t)));
#endif
}
#if ETL_NOT_USING_STL
//*****************************************************************************
/// Fills uninitialised memory range with a value.

View File

@ -0,0 +1,61 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2022 John Wellbelove
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_ADDRESSOF_INCLUDED
#define ETL_ADDRESSOF_INCLUDED
#include "../platform.h"
#if defined(ETL_IN_UNIT_TEST) || ETL_USING_STL
#include <memory>
#endif
///\defgroup memory memory
///\ingroup etl
namespace etl
{
//*****************************************************************************
/// Gets the address of an object.
/// https://en.cppreference.com/w/cpp/memory/addressof
///\ingroup memory
//*****************************************************************************
template <typename T>
ETL_CONSTEXPR17 T* addressof(T& t)
{
#if ETL_USING_STL && ETL_USING_CPP11
return std::addressof(t);
#else
return reinterpret_cast<T*>(&const_cast<char&>(reinterpret_cast<const volatile char&>(t)));
#endif
}
}
#endif

View File

@ -507,7 +507,7 @@ namespace etl
{
// Where to start.
size_t index = position >> log2<Bits_Per_Element>::value;
size_t bit = position;
size_t bit = position & (Bits_Per_Element - 1);
element_type mask = 1 << bit;

View File

@ -31,11 +31,39 @@
#include "platform.h"
#include "atomic.h"
#include "error_handler.h"
#include <stdint.h>
namespace etl
{
//***************************************************************************
/// Exceptions for reference counting
///\ingroup reference_counting
//***************************************************************************
class reference_counting_exception : public etl::exception
{
public:
reference_counting_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
: exception(reason_, file_name_, line_number_)
{
}
};
//***************************************************************************
/// Reference counter overrun exception
///\ingroup reference_counting
//***************************************************************************
class reference_count_overrun : public etl::reference_counting_exception
{
public:
reference_count_overrun(string_type file_name_, numeric_type line_number_)
: etl::reference_counting_exception(ETL_ERROR_TEXT("reference_counting:overrun", ETL_REFERENCE_COUNTED_OBJECT_FILE_ID"A"), file_name_, line_number_)
{
}
};
//***************************************************************************
/// The base of all reference counters.
//***************************************************************************
@ -87,7 +115,7 @@ namespace etl
//***************************************************************************
ETL_NODISCARD virtual int32_t decrement_reference_count() ETL_OVERRIDE
{
assert(reference_count > 0);
ETL_ASSERT(reference_count > 0, ETL_ERROR(reference_count_overrun));
return int32_t(--reference_count);
}

View File

@ -37,14 +37,13 @@ SOFTWARE.
namespace etl
{
template <typename T>
struct scaled_rounding_t
{
typedef typename etl::conditional<etl::is_signed<T>::value, int32_t, uint32_t>::type type;
};
//*****************************************************************************
//*****************************************************************************
/// A set of rounding algorithms for scaled integrals.
/// \tparam T The integral type.
/// \tparam SCALING The scaling factor.
@ -64,7 +63,7 @@ namespace etl
/// \param value Scaled integral.
/// \return Unscaled, rounded integral.
//***************************************************************************
template <const size_t SCALING, typename T>
template <uint32_t SCALING, typename T>
T round_ceiling_unscaled(T value)
{
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
@ -85,7 +84,7 @@ namespace etl
/// \param value Scaled integral.
/// \return Scaled, rounded integral.
//***************************************************************************
template <const size_t SCALING, typename T>
template <uint32_t SCALING, typename T>
T round_ceiling_scaled(T value)
{
typedef typename scaled_rounding_t<T>::type scale_t;
@ -98,7 +97,7 @@ namespace etl
/// \param value Scaled integral.
/// \return Unscaled, rounded integral.
//***************************************************************************
template <const size_t SCALING, typename T>
template <uint32_t SCALING, typename T>
T round_floor_unscaled(T value)
{
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
@ -119,7 +118,7 @@ namespace etl
/// \param value Scaled integral.
/// \return Scaled, rounded integral.
//***************************************************************************
template <const size_t SCALING, typename T>
template <uint32_t SCALING, typename T>
T round_floor_scaled(T value)
{
typedef typename scaled_rounding_t<T>::type scale_t;
@ -133,7 +132,7 @@ namespace etl
/// \param value Scaled integral.
/// \return Unscaled, rounded integral.
//***************************************************************************
template <const size_t SCALING, typename T>
template <uint32_t SCALING, typename T>
T round_half_up_unscaled(T value)
{
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
@ -156,7 +155,7 @@ namespace etl
/// \param value Scaled integral.
/// \return Scaled, rounded integral.
//***************************************************************************
template <const size_t SCALING, typename T>
template <uint32_t SCALING, typename T>
T round_half_up_scaled(T value)
{
typedef typename scaled_rounding_t<T>::type scale_t;
@ -170,7 +169,7 @@ namespace etl
/// \param value Scaled integral.
/// \return Unscaled, rounded integral.
//***************************************************************************
template <const size_t SCALING, typename T>
template <uint32_t SCALING, typename T>
T round_half_down_unscaled(T value)
{
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
@ -193,7 +192,7 @@ namespace etl
/// \param value Scaled integral.
/// \return Scaled, rounded integral.
//***************************************************************************
template <const size_t SCALING, typename T>
template <uint32_t SCALING, typename T>
T round_half_down_scaled(T value)
{
typedef typename scaled_rounding_t<T>::type scale_t;
@ -206,7 +205,7 @@ namespace etl
/// \param value Scaled integral.
/// \return Unscaled, rounded integral.
//***************************************************************************
template <const size_t SCALING, typename T>
template <uint32_t SCALING, typename T>
T round_zero_unscaled(T value)
{
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
@ -220,7 +219,7 @@ namespace etl
/// \param value Scaled integral.
/// \return Scaled, rounded integral.
//***************************************************************************
template <const size_t SCALING, typename T>
template <uint32_t SCALING, typename T>
T round_zero_scaled(T value)
{
typedef typename scaled_rounding_t<T>::type scale_t;
@ -233,7 +232,7 @@ namespace etl
/// \param value Scaled integral.
/// \return Unscaled, rounded integral.
//***************************************************************************
template <const size_t SCALING, typename T>
template <uint32_t SCALING, typename T>
T round_infinity_unscaled(T value)
{
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
@ -254,7 +253,7 @@ namespace etl
/// \param value Scaled integral.
/// \return Scaled, rounded integral.
//***************************************************************************
template <const size_t SCALING, typename T>
template <uint32_t SCALING, typename T>
T round_infinity_scaled(T value)
{
typedef typename scaled_rounding_t<T>::type scale_t;
@ -268,7 +267,7 @@ namespace etl
/// \param value Scaled integral.
/// \return Unscaled, rounded integral.
//***************************************************************************
template <const size_t SCALING, typename T>
template <uint32_t SCALING, typename T>
T round_half_even_unscaled(T value)
{
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
@ -299,7 +298,7 @@ namespace etl
/// \param value Scaled integral.
/// \return Scaled, rounded integral.
//***************************************************************************
template <const size_t SCALING, typename T>
template <uint32_t SCALING, typename T>
T round_half_even_scaled(T value)
{
typedef typename scaled_rounding_t<T>::type scale_t;
@ -313,7 +312,7 @@ namespace etl
/// \param value Scaled integral.
/// \return Unscaled, rounded integral.
//***************************************************************************
template <const size_t SCALING, typename T>
template <uint32_t SCALING, typename T>
T round_half_odd_unscaled(T value)
{
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
@ -344,7 +343,7 @@ namespace etl
/// \param value Scaled integral.
/// \return Scaled, rounded integral.
//***************************************************************************
template <const size_t SCALING, typename T>
template <uint32_t SCALING, typename T>
T round_half_odd_scaled(T value)
{
typedef typename scaled_rounding_t<T>::type scale_t;

View File

@ -58,10 +58,11 @@ namespace etl
static ETL_CONSTANT size_t Size = Size_;
typedef char* pointer;
typedef const char* const_pointer;
typedef char* iterator;
typedef const char* const_iterator;
typedef unsigned char storage_type;
typedef storage_type* pointer;
typedef const storage_type* const_pointer;
typedef storage_type* iterator;
typedef const storage_type* const_iterator;
typedef etl::reverse_iterator<iterator> reverse_iterator;
typedef etl::reverse_iterator<const_iterator> const_reverse_iterator;
@ -196,7 +197,7 @@ namespace etl
//*************************************************************************
/// Index operator.
//*************************************************************************
char& operator[](int i)
storage_type& operator[](int i)
{
return storage[i];
}
@ -204,19 +205,22 @@ namespace etl
//*************************************************************************
/// Const index operator.
//*************************************************************************
ETL_CONSTEXPR const char& operator[](int i) const
ETL_CONSTEXPR const storage_type& operator[](int i) const
{
return storage[i];
}
protected:
char storage[Size];
unsigned char storage[Size];
};
}
//*************************************************************************
/// unaligned_type
///\brief Allows an arithmetic type to be stored at an unaligned address.
///\tparam T The arithmetic type.
///\tparam Endian The endianness of the arithmetic type.
//*************************************************************************
template <typename T, int Endian_>
class unaligned_type : public private_unaligned_type::unaligned_type_common<sizeof(T)>
@ -227,6 +231,14 @@ namespace etl
typedef T value_type;
typedef typename private_unaligned_type::unaligned_type_common<sizeof(T)>::storage_type storage_type;
typedef typename private_unaligned_type::unaligned_type_common<sizeof(T)>::pointer pointer;
typedef typename private_unaligned_type::unaligned_type_common<sizeof(T)>::const_pointer const_pointer;
typedef typename private_unaligned_type::unaligned_type_common<sizeof(T)>::iterator iterator;
typedef typename private_unaligned_type::unaligned_type_common<sizeof(T)>::const_iterator const_iterator;
typedef typename private_unaligned_type::unaligned_type_common<sizeof(T)>::reverse_iterator reverse_iterator;
typedef typename private_unaligned_type::unaligned_type_common<sizeof(T)>::const_reverse_iterator const_reverse_iterator;
static ETL_CONSTANT int Endian = Endian_;
static ETL_CONSTANT size_t Size = private_unaligned_type::unaligned_type_common<sizeof(T)>::Size;
@ -356,68 +368,70 @@ namespace etl
struct unaligned_copy;
//*******************************************
// Size == 1
/// Unaligned copy
/// Size == 1
//*******************************************
template <typename U>
struct unaligned_copy<U, 1U>
{
//*******************************
static ETL_CONSTEXPR14 void copy(T value, char* store)
static ETL_CONSTEXPR14 void copy(T value, pointer store)
{
store[0] = static_cast<char>(value);
store[0] = static_cast<storage_type>(value);
}
//*******************************
static ETL_CONSTEXPR14 void copy(const char* store, T& value)
static ETL_CONSTEXPR14 void copy(const_pointer store, T& value)
{
value = static_cast<T>(store[0]);
}
//*******************************
static ETL_CONSTEXPR14 void copy(const char* src, int /*endian_src*/, char* dst)
static ETL_CONSTEXPR14 void copy(const_pointer src, int /*endian_src*/, pointer dst)
{
dst[0] = src[0];
}
};
//*******************************************
// Size == 2
/// Unaligned copy
/// Size == 2
//*******************************************
template <typename U>
struct unaligned_copy<U, 2U>
{
//*******************************
static ETL_CONSTEXPR14 void copy(T value, char* store)
static ETL_CONSTEXPR14 void copy(T value, pointer store)
{
if (Endian == etl::endianness::value())
{
store[0] = static_cast<char>(value);
store[1] = static_cast<char>(value >> (1U * CHAR_BIT));
store[0] = static_cast<storage_type>(value);
store[1] = static_cast<storage_type>(value >> (1U * CHAR_BIT));
}
else
{
store[1] = static_cast<char>(value);
store[0] = static_cast<char>(value >> (1U * CHAR_BIT));
store[1] = static_cast<storage_type>(value);
store[0] = static_cast<storage_type>(value >> (1U * CHAR_BIT));
}
}
//*******************************
static ETL_CONSTEXPR14 void copy(const char* store, T& value)
static ETL_CONSTEXPR14 void copy(const_pointer store, T& value)
{
if (Endian == etl::endianness::value())
{
value = static_cast<T>(static_cast<unsigned char>(store[0]));
value |= static_cast<T>(static_cast<unsigned char>(store[1])) << (1U * CHAR_BIT);
value = static_cast<T>(store[0]);
value |= static_cast<T>(store[1]) << (1U * CHAR_BIT);
}
else
{
value = static_cast<T>(static_cast<unsigned char>(store[1]));
value |= static_cast<T>(static_cast<unsigned char>(store[0])) << (1U * CHAR_BIT);
value = static_cast<T>(store[1]);
value |= static_cast<T>(store[0]) << (1U * CHAR_BIT);
}
}
//*******************************
static ETL_CONSTEXPR14 void copy(const char* src, int endian_src, char* dst)
static ETL_CONSTEXPR14 void copy(const_pointer src, int endian_src, pointer dst)
{
if (Endian == endian_src)
{
@ -433,50 +447,51 @@ namespace etl
};
//*******************************************
// Size == 4
/// Unaligned copy
/// Size == 4
//*******************************************
template <typename U>
struct unaligned_copy<U, 4U>
{
static ETL_CONSTEXPR14 void copy(T value, char* store)
static ETL_CONSTEXPR14 void copy(T value, pointer store)
{
if (Endian == etl::endianness::value())
{
store[0] = static_cast<char>(value);
store[1] = static_cast<char>(value >> (1U * CHAR_BIT));
store[2] = static_cast<char>(value >> (2U * CHAR_BIT));
store[3] = static_cast<char>(value >> (3U * CHAR_BIT));
store[0] = static_cast<storage_type>(value);
store[1] = static_cast<storage_type>(value >> (1U * CHAR_BIT));
store[2] = static_cast<storage_type>(value >> (2U * CHAR_BIT));
store[3] = static_cast<storage_type>(value >> (3U * CHAR_BIT));
}
else
{
store[3] = static_cast<char>(value);
store[2] = static_cast<char>(value >> (1U * CHAR_BIT));
store[1] = static_cast<char>(value >> (2U * CHAR_BIT));
store[0] = static_cast<char>(value >> (3U * CHAR_BIT));
store[3] = static_cast<storage_type>(value);
store[2] = static_cast<storage_type>(value >> (1U * CHAR_BIT));
store[1] = static_cast<storage_type>(value >> (2U * CHAR_BIT));
store[0] = static_cast<storage_type>(value >> (3U * CHAR_BIT));
}
}
//*******************************
static ETL_CONSTEXPR14 void copy(const char* store, T& value)
static ETL_CONSTEXPR14 void copy(const_pointer store, T& value)
{
if (Endian == etl::endianness::value())
{
value = static_cast<T>(static_cast<unsigned char>(store[0]));
value |= static_cast<T>(static_cast<unsigned char>(store[1])) << (1U * CHAR_BIT);
value |= static_cast<T>(static_cast<unsigned char>(store[2])) << (2U * CHAR_BIT);
value |= static_cast<T>(static_cast<unsigned char>(store[3])) << (3U * CHAR_BIT);
value = static_cast<T>(store[0]);
value |= static_cast<T>(store[1]) << (1U * CHAR_BIT);
value |= static_cast<T>(store[2]) << (2U * CHAR_BIT);
value |= static_cast<T>(store[3]) << (3U * CHAR_BIT);
}
else
{
value = static_cast<T>(static_cast<unsigned char>(store[3]));
value |= static_cast<T>(static_cast<unsigned char>(store[2])) << (1U * CHAR_BIT);
value |= static_cast<T>(static_cast<unsigned char>(store[1])) << (2U * CHAR_BIT);
value |= static_cast<T>(static_cast<unsigned char>(store[0])) << (3U * CHAR_BIT);
value = static_cast<T>(store[3]);
value |= static_cast<T>(store[2]) << (1U * CHAR_BIT);
value |= static_cast<T>(store[1]) << (2U * CHAR_BIT);
value |= static_cast<T>(store[0]) << (3U * CHAR_BIT);
}
}
//*******************************
static ETL_CONSTEXPR14 void copy(const char* src, int endian_src, char* dst)
static ETL_CONSTEXPR14 void copy(const_pointer src, int endian_src, pointer dst)
{
if (Endian == endian_src)
{
@ -496,66 +511,67 @@ namespace etl
};
//*******************************************
// Size == 8
/// Unaligned copy
/// Size == 8
//*******************************************
template <typename U>
struct unaligned_copy<U, 8U>
{
static ETL_CONSTEXPR14 void copy(T value, char* store)
static ETL_CONSTEXPR14 void copy(T value, pointer store)
{
if (Endian == etl::endianness::value())
{
store[0] = static_cast<char>(value);
store[1] = static_cast<char>(value >> (1U * CHAR_BIT));
store[2] = static_cast<char>(value >> (2U * CHAR_BIT));
store[3] = static_cast<char>(value >> (3U * CHAR_BIT));
store[4] = static_cast<char>(value >> (4U * CHAR_BIT));
store[5] = static_cast<char>(value >> (5U * CHAR_BIT));
store[6] = static_cast<char>(value >> (6U * CHAR_BIT));
store[7] = static_cast<char>(value >> (7U * CHAR_BIT));
store[0] = static_cast<storage_type>(value);
store[1] = static_cast<storage_type>(value >> (1U * CHAR_BIT));
store[2] = static_cast<storage_type>(value >> (2U * CHAR_BIT));
store[3] = static_cast<storage_type>(value >> (3U * CHAR_BIT));
store[4] = static_cast<storage_type>(value >> (4U * CHAR_BIT));
store[5] = static_cast<storage_type>(value >> (5U * CHAR_BIT));
store[6] = static_cast<storage_type>(value >> (6U * CHAR_BIT));
store[7] = static_cast<storage_type>(value >> (7U * CHAR_BIT));
}
else
{
store[7] = static_cast<char>(value);
store[6] = static_cast<char>(value >> (1U * CHAR_BIT));
store[5] = static_cast<char>(value >> (2U * CHAR_BIT));
store[4] = static_cast<char>(value >> (3U * CHAR_BIT));
store[3] = static_cast<char>(value >> (4U * CHAR_BIT));
store[2] = static_cast<char>(value >> (5U * CHAR_BIT));
store[1] = static_cast<char>(value >> (6U * CHAR_BIT));
store[0] = static_cast<char>(value >> (7U * CHAR_BIT));
store[7] = static_cast<storage_type>(value);
store[6] = static_cast<storage_type>(value >> (1U * CHAR_BIT));
store[5] = static_cast<storage_type>(value >> (2U * CHAR_BIT));
store[4] = static_cast<storage_type>(value >> (3U * CHAR_BIT));
store[3] = static_cast<storage_type>(value >> (4U * CHAR_BIT));
store[2] = static_cast<storage_type>(value >> (5U * CHAR_BIT));
store[1] = static_cast<storage_type>(value >> (6U * CHAR_BIT));
store[0] = static_cast<storage_type>(value >> (7U * CHAR_BIT));
}
}
//*******************************
static ETL_CONSTEXPR14 void copy(const char* store, T& value)
static ETL_CONSTEXPR14 void copy(const_pointer store, T& value)
{
if (Endian == etl::endianness::value())
{
value = static_cast<T>(static_cast<unsigned char>(store[0]));
value |= static_cast<T>(static_cast<unsigned char>(store[1])) << (1U * CHAR_BIT);
value |= static_cast<T>(static_cast<unsigned char>(store[2])) << (2U * CHAR_BIT);
value |= static_cast<T>(static_cast<unsigned char>(store[3])) << (3U * CHAR_BIT);
value |= static_cast<T>(static_cast<unsigned char>(store[4])) << (4U * CHAR_BIT);
value |= static_cast<T>(static_cast<unsigned char>(store[5])) << (5U * CHAR_BIT);
value |= static_cast<T>(static_cast<unsigned char>(store[6])) << (6U * CHAR_BIT);
value |= static_cast<T>(static_cast<unsigned char>(store[7])) << (7U * CHAR_BIT);
value = static_cast<T>(store[0]);
value |= static_cast<T>(store[1]) << (1U * CHAR_BIT);
value |= static_cast<T>(store[2]) << (2U * CHAR_BIT);
value |= static_cast<T>(store[3]) << (3U * CHAR_BIT);
value |= static_cast<T>(store[4]) << (4U * CHAR_BIT);
value |= static_cast<T>(store[5]) << (5U * CHAR_BIT);
value |= static_cast<T>(store[6]) << (6U * CHAR_BIT);
value |= static_cast<T>(store[7]) << (7U * CHAR_BIT);
}
else
{
value = static_cast<T>(static_cast<unsigned char>(store[7]));
value |= static_cast<T>(static_cast<unsigned char>(store[6])) << (1U * CHAR_BIT);
value |= static_cast<T>(static_cast<unsigned char>(store[5])) << (2U * CHAR_BIT);
value |= static_cast<T>(static_cast<unsigned char>(store[4])) << (3U * CHAR_BIT);
value |= static_cast<T>(static_cast<unsigned char>(store[3])) << (4U * CHAR_BIT);
value |= static_cast<T>(static_cast<unsigned char>(store[2])) << (5U * CHAR_BIT);
value |= static_cast<T>(static_cast<unsigned char>(store[1])) << (6U * CHAR_BIT);
value |= static_cast<T>(static_cast<unsigned char>(store[0])) << (7U * CHAR_BIT);
value = static_cast<T>(store[7]);
value |= static_cast<T>(store[6]) << (1U * CHAR_BIT);
value |= static_cast<T>(store[5]) << (2U * CHAR_BIT);
value |= static_cast<T>(store[4]) << (3U * CHAR_BIT);
value |= static_cast<T>(store[3]) << (4U * CHAR_BIT);
value |= static_cast<T>(store[2]) << (5U * CHAR_BIT);
value |= static_cast<T>(store[1]) << (6U * CHAR_BIT);
value |= static_cast<T>(store[0]) << (7U * CHAR_BIT);
}
}
//*******************************
static ETL_CONSTEXPR14 void copy(const char* src, int endian_src, char* dst)
static ETL_CONSTEXPR14 void copy(const_pointer src, int endian_src, pointer dst)
{
if (Endian == endian_src)
{

View File

@ -967,7 +967,7 @@ namespace etl
local_iterator icurrent = bucket.begin();
// Search for the key, if we have it.
while ((icurrent != bucket.end()) && (icurrent->key_value_pair.first != key))
while ((icurrent != bucket.end()) && (!key_equal_function(icurrent->key_value_pair.first, key)))
{
++iprevious;
++icurrent;

View File

@ -983,7 +983,7 @@ namespace etl
++l;
++n;
while ((l != end()) && (key == l->first))
while ((l != end()) && key_equal_function(key, l->first))
{
++l;
++n;
@ -1078,7 +1078,7 @@ namespace etl
{
++l;
while ((l != end()) && (key == l->first))
while ((l != end()) && key_equal_function(key, l->first))
{
++l;
}
@ -1104,7 +1104,7 @@ namespace etl
{
++l;
while ((l != end()) && (key == l->first))
while ((l != end()) && key_equal_function(key, l->first))
{
++l;
}

View File

@ -964,7 +964,7 @@ namespace etl
++l;
++n;
while ((l != end()) && (key == *l))
while ((l != end()) && key_equal_function(key, *l))
{
++l;
++n;
@ -1059,7 +1059,7 @@ namespace etl
{
++l;
while ((l != end()) && (key == *l))
while ((l != end()) && key_equal_function(key, *l))
{
++l;
}
@ -1085,7 +1085,7 @@ namespace etl
{
++l;
while ((l != end()) && (key == *l))
while ((l != end()) && key_equal_function(key, *l))
{
++l;
}

View File

@ -846,7 +846,7 @@ namespace etl
local_iterator icurrent = bucket.begin();
// Search for the key, if we have it.
while ((icurrent != bucket.end()) && (icurrent->key != key))
while ((icurrent != bucket.end()) && (!key_equal_function(icurrent->key, key)))
{
++iprevious;
++icurrent;

View File

@ -93,24 +93,36 @@ namespace etl
}
#endif
//******************************************************************************
//***************************************************************************
///\brief pair holds two objects of arbitrary type
///
///\tparam T1, T2 The types of the elements that the pair stores
//***************************************************************************
template <typename T1, typename T2>
struct pair
{
typedef T1 first_type;
typedef T2 second_type;
typedef T1 first_type; ///< @c first_type is the first bound type
typedef T2 second_type; ///< @c second_type is the second bound type
T1 first;
T2 second;
T1 first; ///< @c first is a copy of the first object
T2 second; ///< @c second is a copy of the second object
/// Default constructor
//***************************************************************************
///\brief Default constructor
///
/// The default constructor creates @c first and @c second using their respective default constructors.
//***************************************************************************
ETL_CONSTEXPR pair()
: first(T1())
, second(T2())
{
}
/// Constructor from parameters
//***************************************************************************
///\brief Constructor from parameters
///
/// Two objects may be passed to a @c pair constructor to be copied.
//***************************************************************************
ETL_CONSTEXPR14 pair(const T1& a, const T2& b)
: first(a)
, second(b)
@ -118,7 +130,9 @@ namespace etl
}
#if ETL_USING_CPP11
/// Move constructor from parameters
//***************************************************************************
///\brief Move constructor from parameters.
//***************************************************************************
template <typename U1, typename U2>
ETL_CONSTEXPR14 pair(U1&& a, U2&& b)
: first(etl::forward<U1>(a))
@ -127,7 +141,11 @@ namespace etl
}
#endif
/// Copy constructor
//***************************************************************************
///\brief Copy constructor
///
/// There is also a templated copy constructor for the @c pair class itself.
//***************************************************************************
template <typename U1, typename U2>
ETL_CONSTEXPR14 pair(const pair<U1, U2>& other)
: first(other.first)
@ -224,7 +242,14 @@ namespace etl
#endif
};
//******************************************************************************
//***************************************************************************
///\brief A convenience wrapper for creating a @ref pair from two objects.
///
///\param a The first object.
///\param b The second object.
///
///\return A newly-constructed @ref pair object of the appropriate type.
//***************************************************************************
#if ETL_USING_CPP11
template <typename T1, typename T2>
inline pair<T1, T2> make_pair(T1&& a, T2&& b)
@ -246,13 +271,14 @@ namespace etl
a.swap(b);
}
//******************************************************************************
/// Two pairs of the same type are equal iff their members are equal.
template <typename T1, typename T2>
inline bool operator ==(const pair<T1, T2>& a, const pair<T1, T2>& b)
{
return (a.first == b.first) && (a.second == b.second);
}
/// Uses @c operator== to find the result.
template <typename T1, typename T2>
inline bool operator !=(const pair<T1, T2>& a, const pair<T1, T2>& b)
{
@ -266,24 +292,97 @@ namespace etl
(!(b.first < a.first) && (a.second < b.second));
}
/// Uses @c operator< to find the result.
template <typename T1, typename T2>
inline bool operator >(const pair<T1, T2>& a, const pair<T1, T2>& b)
{
return (b < a);
}
/// Uses @c operator< to find the result.
template <typename T1, typename T2>
inline bool operator <=(const pair<T1, T2>& a, const pair<T1, T2>& b)
{
return !(b < a);
}
/// Uses @c operator< to find the result.
template <typename T1, typename T2>
inline bool operator >=(const pair<T1, T2>& a, const pair<T1, T2>& b)
{
return !(a < b);
}
//***************************************************************************
///\brief Functor to select @ref pair::first
///
///\ref select1st is a functor object that takes a single argument, a @ref pair, and returns the @ref pair::first element.
///
///\b Example
///\snippet test_utility.cpp test_select1st_example
///
///\tparam TPair The function object's argument type.
///
///\see select2nd
//***************************************************************************
template <typename TPair>
struct select1st
{
typedef typename TPair::first_type type; ///< type of member @ref pair::first.
//***************************************************************************
///\brief Function call that return @c p.first.
///\return a reference to member @ref pair::first of the @c pair `p`
//***************************************************************************
type& operator()(TPair& p) const
{
return p.first;
}
//***************************************************************************
///\copydoc operator()(TPair&)const
//
const type& operator()(const TPair& p) const
{
return p.first;
}
};
//***************************************************************************
///\brief Functor to select @ref pair::second
///
///\ref select2nd is a functor object that takes a single argument, a @ref pair, and returns the @ref pair::second element.
///
///\b Example
///\snippet test_utility.cpp test_select2nd_example
///
///\tparam TPair The function object's argument type.
///
///\see select1st
//***************************************************************************
template <typename TPair>
struct select2nd
{
typedef typename TPair::second_type type; ///< type of member @ref pair::second.
//***************************************************************************
///\brief Function call. The return value is `p.second`.
///\return a reference to member `second` of the pair `p`.
//***************************************************************************
type& operator()(TPair& p) const
{
return p.second;
}
//***************************************************************************
///\copydoc operator()(TPair&)const
//***************************************************************************
const type& operator()(const TPair& p) const
{
return p.second;
}
};
#if ETL_NOT_USING_STL || ETL_CPP14_NOT_SUPPORTED
//***************************************************************************
/// exchange (const)

View File

@ -1 +1 @@
option('use_stl', type : 'boolean', value : true)
option('use_stl', description: 'Compiling for STL', type: 'boolean', value: true)

View File

@ -0,0 +1,9 @@
[wrap-file]
directory = unittest-cpp-2.0.0
source_url = https://github.com/unittest-cpp/unittest-cpp/archive/v2.0.0.zip
source_filename = unittest-cpp-2.0.0.zip
source_hash = 3ba4f8b6c6e75ca8c79dd6008c78e95fb08554fbf2e0f1195fb78a4bf5a8a805
patch_url = https://wrapdb.mesonbuild.com/v2/unittest-cpp_2.0.0-1/get_patch
patch_filename = unittest-cpp-2.0.0-1-wrap.zip
patch_hash = a887de2b619c13fc4fd8bff844ca7015a2046dc613ae0765dd4452ff70db12ca

View File

@ -1,38 +1,7 @@
cmake_minimum_required(VERSION 3.5.0)
project(etl_unit_tests)
project(etl_unit_tests LANGUAGES CXX)
add_definitions(-DETL_DEBUG)
option(ETL_NO_STL "No STL" OFF)
if (NO_STL OR ETL_NO_STL)
message(STATUS "Compiling for No STL")
add_definitions(-DETL_NO_STL)
else()
message(STATUS "Compiling for STL")
endif()
if (ETL_USE_TYPE_TRAITS_BUILTINS)
message(STATUS "Compiling for built-in type traits")
add_definitions(-DETL_USE_TYPE_TRAITS_BUILTINS)
endif()
if (ETL_USE_MEM_BUILTINS)
message(STATUS "Compiling for built-in memory functions")
add_definitions(-DETL_USE_MEM_BUILTINS)
endif()
if (ETL_USER_DEFINED_TYPE_TRAITS)
message(STATUS "Compiling for user defined type traits")
add_definitions(-DETL_USER_DEFINED_TYPE_TRAITS)
endif()
if (ETL_FORCE_TEST_CPP03_IMPLEMENTATION)
message(STATUS "Compiling for C++03 tests")
add_definitions(-DETL_FORCE_TEST_CPP03_IMPLEMENTATION)
endif()
set(TEST_SOURCE_FILES
add_executable(etl_tests
main.cpp
murmurhash3.cpp
test_algorithm.cpp
@ -294,88 +263,59 @@ set(TEST_SOURCE_FILES
test_xor_checksum.cpp
test_xor_rotate_checksum.cpp
)
set(UNITTEST_SOURCE_FILES
UnitTest++/AssertException.cpp
UnitTest++/Checks.cpp
UnitTest++/CompositeTestReporter.cpp
UnitTest++/CurrentTest.cpp
UnitTest++/DeferredTestReporter.cpp
UnitTest++/DeferredTestResult.cpp
UnitTest++/MemoryOutStream.cpp
UnitTest++/ReportAssert.cpp
UnitTest++/RequiredCheckException.cpp
UnitTest++/RequiredCheckTestReporter.cpp
UnitTest++/Test.cpp
UnitTest++/TestDetails.cpp
UnitTest++/TestList.cpp
UnitTest++/TestReporter.cpp
UnitTest++/TestReporterStdout.cpp
UnitTest++/TestResults.cpp
UnitTest++/TestRunner.cpp
UnitTest++/ThrowingTestReporter.cpp
UnitTest++/TimeConstraint.cpp
UnitTest++/XmlTestReporter.cpp
)
set(UNITTEST_DIR
UnitTest++
)
target_compile_definitions(etl_tests PRIVATE -DETL_DEBUG)
if (WIN32)
set(UNITTEST_SOURCE_FILES
${UNITTEST_SOURCE_FILES}
UnitTest++/Win32/TimeHelpers.cpp
)
else ()
set(UNITTEST_SOURCE_FILES
${UNITTEST_SOURCE_FILES}
UnitTest++/Posix/SignalTranslator.cpp
UnitTest++/Posix/TimeHelpers.cpp
)
endif ()
option(ETL_NO_STL "No STL" OFF)
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
message(STATUS "Using MSVC")
endif()
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
message(STATUS "Using GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address,undefined")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
endif()
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
message(STATUS "Using Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address,undefined")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
endif()
add_executable(etl_tests ${TEST_SOURCE_FILES})
add_library(unit_test ${UNITTEST_SOURCE_FILES})
include_directories(${PROJECT_SOURCE_DIR}/../include)
target_include_directories(etl_tests SYSTEM PRIVATE ${UNITTEST_DIR})
target_include_directories(etl_tests PUBLIC ${CMAKE_CURRENT_LIST_DIR})
if(UNIX AND NOT APPLE)
# atomic is need on Linux with Clang
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(etl_tests unit_test atomic Threads::Threads)
elseif(NOT UNIX AND APPLE)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(etl_tests unit_test)
if (NO_STL OR ETL_NO_STL)
message(STATUS "Compiling for No STL")
target_compile_definitions(etl_tests PRIVATE -DETL_NO_STL)
else()
target_link_libraries(etl_tests unit_test)
message(STATUS "Compiling for STL")
endif()
if (ETL_USE_TYPE_TRAITS_BUILTINS)
message(STATUS "Compiling for built-in type traits")
target_compile_definitions(etl_tests PRIVATE -DETL_USE_TYPE_TRAITS_BUILTINS)
endif()
if (ETL_USE_MEM_BUILTINS)
message(STATUS "Compiling for built-in memory functions")
target_compile_definitions(etl_tests PRIVATE -DETL_USE_MEM_BUILTINS)
endif()
if (ETL_USER_DEFINED_TYPE_TRAITS)
message(STATUS "Compiling for user defined type traits")
target_compile_definitions(etl_tests PRIVATE -DETL_USER_DEFINED_TYPE_TRAITS)
endif()
if (ETL_FORCE_TEST_CPP03_IMPLEMENTATION)
message(STATUS "Compiling for C++03 tests")
target_compile_definitions(etl_tests PRIVATE -DETL_FORCE_TEST_CPP03_IMPLEMENTATION)
endif()
target_include_directories(etl_tests
PRIVATE
${PROJECT_SOURCE_DIR}/../include)
add_subdirectory(UnitTest++)
target_link_libraries(etl_tests PRIVATE UnitTestpp)
if ((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
target_compile_options(etl_tests
PRIVATE
-fsanitize=address,undefined
-Wall
-Wextra
-Werror
)
target_link_options(etl_tests
PRIVATE
-fsanitize=address,undefined
)
endif ()
# Enable the 'make test' CMake target using the executable defined above
add_test(etl_unit_tests etl_tests)

View File

@ -0,0 +1,51 @@
cmake_minimum_required(VERSION 3.5.0)
project(UnitTestpp LANGUAGES CXX)
add_library(UnitTestpp
AssertException.cpp
Checks.cpp
CompositeTestReporter.cpp
CurrentTest.cpp
DeferredTestReporter.cpp
DeferredTestResult.cpp
MemoryOutStream.cpp
ReportAssert.cpp
RequiredCheckException.cpp
RequiredCheckTestReporter.cpp
Test.cpp
TestDetails.cpp
TestList.cpp
TestReporter.cpp
TestReporterStdout.cpp
TestResults.cpp
TestRunner.cpp
ThrowingTestReporter.cpp
TimeConstraint.cpp
XmlTestReporter.cpp
)
target_include_directories(UnitTestpp SYSTEM INTERFACE ..)
if (WIN32)
target_sources(UnitTestpp PRIVATE Win32/TimeHelpers.cpp)
else ()
target_sources(UnitTestpp PRIVATE
Posix/SignalTranslator.cpp
Posix/TimeHelpers.cpp
)
endif ()
if ((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
target_compile_options(UnitTestpp PRIVATE -fexceptions)
endif ()
if (UNIX AND NOT APPLE)
# atomic is need on Linux with Clang
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(UnitTestpp PRIVATE atomic Threads::Threads)
elseif (NOT UNIX AND APPLE)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(UnitTestpp PRIVATE Threads::Threads)
endif ()

View File

@ -1,247 +1,272 @@
etl_test_sources = files(
'main.cpp',
'murmurhash3.cpp',
'test_algorithm.cpp',
'test_alignment.cpp',
'test_array.cpp',
'test_array_view.cpp',
'test_array_wrapper.cpp',
'test_atomic_clang_sync.cpp',
'test_atomic_gcc_sync.cpp',
'test_atomic_std.cpp',
'test_binary.cpp',
'test_bip_buffer_spsc_atomic.cpp',
'test_bitset.cpp',
'test_bit_stream.cpp',
'test_bloom_filter.cpp',
'test_bresenham_line.cpp',
'test_bsd_checksum.cpp',
'test_buffer_descriptors.cpp',
'test_byte_stream.cpp',
'test_callback_service.cpp',
'test_callback_timer.cpp',
'test_checksum.cpp',
'test_circular_buffer.cpp',
'test_circular_buffer_external_buffer.cpp',
'test_compare.cpp',
'test_compiler_settings.cpp',
'test_constant.cpp',
'test_container.cpp',
'test_correlation.cpp',
'test_covariance.cpp',
'test_crc.cpp',
'test_crc16.cpp',
'test_crc16_a.cpp',
'test_crc16_arc.cpp',
'test_crc16_aug_ccitt.cpp',
'test_crc16_buypass.cpp',
'test_crc16_ccitt.cpp',
'test_crc16_cdma2000.cpp',
'test_crc16_dds110.cpp',
'test_crc16_dectr.cpp',
'test_crc16_dectx.cpp',
'test_crc16_dnp.cpp',
'test_crc16_en13757.cpp',
'test_crc16_genibus.cpp',
'test_crc16_kermit.cpp',
'test_crc16_maxim.cpp',
'test_crc16_mcrf4xx.cpp',
'test_crc16_modbus.cpp',
'test_crc16_profibus.cpp',
'test_crc16_riello.cpp',
'test_crc16_t10dif.cpp',
'test_crc16_teledisk.cpp',
'test_crc16_tms37157.cpp',
'test_crc16_usb.cpp',
'test_crc16_x25.cpp',
'test_crc16_xmodem.cpp',
'test_crc32.cpp',
'test_crc32_bzip2.cpp',
'test_crc32_c.cpp',
'test_crc32_d.cpp',
'test_crc32_jamcrc.cpp',
'test_crc32_mpeg2.cpp',
'test_crc32_posix.cpp',
'test_crc32_q.cpp',
'test_crc32_xfer.cpp',
'test_crc64_ecma.cpp',
'test_crc8_ccitt.cpp',
'test_crc8_cdma2000.cpp',
'test_crc8_darc.cpp',
'test_crc8_dvbs2.cpp',
'test_crc8_ebu.cpp',
'test_crc8_icode.cpp',
'test_crc8_itu.cpp',
'test_crc8_maxim.cpp',
'test_crc8_rohc.cpp',
'test_crc8_wcdma.cpp',
'test_cumulative_moving_average.cpp',
'test_cyclic_value.cpp',
'test_debounce.cpp',
'test_delegate.cpp',
'test_delegate_service.cpp',
'test_delegate_service_compile_time.cpp',
'test_deque.cpp',
'test_endian.cpp',
'test_enum_type.cpp',
'test_error_handler.cpp',
'test_exception.cpp',
'test_fixed_iterator.cpp',
'test_fixed_sized_memory_block_allocator.cpp',
'test_flags.cpp',
'test_flat_map.cpp',
'test_flat_multimap.cpp',
'test_flat_multiset.cpp',
'test_flat_set.cpp',
'test_fnv_1.cpp',
'test_format_spec.cpp',
'test_forward_list.cpp',
'test_forward_list_shared_pool.cpp',
'test_fsm.cpp',
'test_function.cpp',
'test_functional.cpp',
'test_gamma.cpp',
'test_hash.cpp',
'test_hfsm.cpp',
'test_histogram.cpp',
'test_indirect_vector.cpp',
'test_indirect_vector_external_buffer.cpp',
'test_instance_count.cpp',
'test_integral_limits.cpp',
'test_intrusive_forward_list.cpp',
'test_intrusive_links.cpp',
'test_intrusive_list.cpp',
'test_intrusive_queue.cpp',
'test_intrusive_stack.cpp',
'test_invert.cpp',
'test_io_port.cpp',
'test_iterator.cpp',
'test_jenkins.cpp',
'test_largest.cpp',
'test_limiter.cpp',
'test_limits.cpp',
'test_list.cpp',
'test_list_shared_pool.cpp',
'test_make_string.cpp',
'test_map.cpp',
'test_maths.cpp',
'test_mean.cpp',
'main.cpp',
'murmurhash3.cpp',
'test_algorithm.cpp',
'test_alignment.cpp',
'test_array.cpp',
'test_array_view.cpp',
'test_array_wrapper.cpp',
'test_atomic.cpp',
'test_binary.cpp',
'test_bip_buffer_spsc_atomic.cpp',
'test_bit.cpp',
'test_bitset_legacy.cpp',
'test_bitset_new_default_element_type.cpp',
'test_bitset_new_explicit_single_element_type.cpp',
'test_bitset_new_ext_default_element_type.cpp',
'test_bitset_new_ext_explicit_single_element_type.cpp',
'test_bit_stream.cpp',
'test_bit_stream_reader_big_endian.cpp',
'test_bit_stream_reader_little_endian.cpp',
'test_bit_stream_writer_big_endian.cpp',
'test_bit_stream_writer_little_endian.cpp',
'test_byte.cpp',
'test_byte_stream.cpp',
'test_bloom_filter.cpp',
'test_bresenham_line.cpp',
'test_bsd_checksum.cpp',
'test_buffer_descriptors.cpp',
'test_callback_service.cpp',
'test_callback_timer.cpp',
'test_callback_timer_atomic.cpp',
'test_callback_timer_interrupt.cpp',
'test_callback_timer_locked.cpp',
'test_checksum.cpp',
'test_circular_buffer.cpp',
'test_circular_buffer_external_buffer.cpp',
'test_circular_iterator.cpp',
'test_compare.cpp',
'test_compiler_settings.cpp',
'test_constant.cpp',
'test_container.cpp',
'test_correlation.cpp',
'test_covariance.cpp',
'test_crc.cpp',
'test_crc16.cpp',
'test_crc16_a.cpp',
'test_crc16_arc.cpp',
'test_crc16_aug_ccitt.cpp',
'test_crc16_buypass.cpp',
'test_crc16_ccitt.cpp',
'test_crc16_cdma2000.cpp',
'test_crc16_dds110.cpp',
'test_crc16_dectr.cpp',
'test_crc16_dectx.cpp',
'test_crc16_dnp.cpp',
'test_crc16_en13757.cpp',
'test_crc16_genibus.cpp',
'test_crc16_kermit.cpp',
'test_crc16_maxim.cpp',
'test_crc16_mcrf4xx.cpp',
'test_crc16_modbus.cpp',
'test_crc16_profibus.cpp',
'test_crc16_riello.cpp',
'test_crc16_t10dif.cpp',
'test_crc16_teledisk.cpp',
'test_crc16_tms37157.cpp',
'test_crc16_usb.cpp',
'test_crc16_x25.cpp',
'test_crc16_xmodem.cpp',
'test_crc32.cpp',
'test_crc32_bzip2.cpp',
'test_crc32_c.cpp',
'test_crc32_d.cpp',
'test_crc32_jamcrc.cpp',
'test_crc32_mpeg2.cpp',
'test_crc32_posix.cpp',
'test_crc32_q.cpp',
'test_crc32_xfer.cpp',
'test_crc64_ecma.cpp',
'test_crc8_ccitt.cpp',
'test_crc8_cdma2000.cpp',
'test_crc8_darc.cpp',
'test_crc8_dvbs2.cpp',
'test_crc8_ebu.cpp',
'test_crc8_icode.cpp',
'test_crc8_itu.cpp',
'test_crc8_maxim.cpp',
'test_crc8_rohc.cpp',
'test_crc8_wcdma.cpp',
'test_cyclic_value.cpp',
'test_debounce.cpp',
'test_delegate.cpp',
'test_delegate_cpp03.cpp',
'test_delegate_service.cpp',
'test_delegate_service_compile_time.cpp',
'test_deque.cpp',
'test_endian.cpp',
'test_enum_type.cpp',
'test_error_handler.cpp',
'test_etl_traits.cpp',
'test_exception.cpp',
'test_fixed_iterator.cpp',
'test_fixed_sized_memory_block_allocator.cpp',
'test_flags.cpp',
'test_flat_map.cpp',
'test_flat_multimap.cpp',
'test_flat_multiset.cpp',
'test_flat_set.cpp',
'test_fnv_1.cpp',
'test_format_spec.cpp',
'test_forward_list.cpp',
'test_forward_list_shared_pool.cpp',
'test_fsm.cpp',
'test_function.cpp',
'test_functional.cpp',
'test_gamma.cpp',
'test_hash.cpp',
'test_hfsm.cpp',
'test_histogram.cpp',
'test_indirect_vector.cpp',
'test_indirect_vector_external_buffer.cpp',
'test_instance_count.cpp',
'test_integral_limits.cpp',
'test_intrusive_forward_list.cpp',
'test_intrusive_links.cpp',
'test_intrusive_list.cpp',
'test_intrusive_queue.cpp',
'test_intrusive_stack.cpp',
'test_invert.cpp',
'test_io_port.cpp',
'test_iterator.cpp',
'test_jenkins.cpp',
'test_largest.cpp',
'test_limiter.cpp',
'test_limits.cpp',
'test_list.cpp',
'test_list_shared_pool.cpp',
'test_make_string.cpp',
'test_map.cpp',
'test_maths.cpp',
'test_mean.cpp',
'test_mem_cast.cpp',
'test_mem_cast_ptr.cpp',
'test_memory.cpp',
'test_mem_cast.cpp',
'test_mem_cast_ptr.cpp',
#'test_mem_type.cpp',
'test_message_bus.cpp',
'test_message_packet.cpp',
'test_message_router.cpp',
'test_message_router_registry.cpp',
'test_message_timer.cpp',
'test_multimap.cpp',
'test_multiset.cpp',
'test_multi_array.cpp',
'test_multi_range.cpp',
'test_multi_span.cpp',
'test_multi_vector.cpp',
'test_murmur3.cpp',
'test_numeric.cpp',
'test_observer.cpp',
'test_optional.cpp',
'test_overload.cpp',
'test_packet.cpp',
'test_parameter_pack.cpp',
'test_parameter_type.cpp',
'test_parity_checksum.cpp',
'test_pearson.cpp',
'test_pool.cpp',
'test_pool_external_buffer.cpp',
'test_priority_queue.cpp',
'test_quantize.cpp',
'test_queue.cpp',
'test_queue_lockable.cpp',
'test_queue_lockable_small.cpp',
'test_queue_memory_model_small.cpp',
'test_queue_mpmc_mutex.cpp',
'test_queue_mpmc_mutex_small.cpp',
'test_queue_spsc_atomic.cpp',
'test_queue_spsc_atomic_small.cpp',
'test_queue_spsc_isr.cpp',
'test_queue_spsc_isr_small.cpp',
'test_queue_spsc_locked.cpp',
'test_queue_spsc_locked_small.cpp',
'test_random.cpp',
'test_reference_flat_map.cpp',
'test_reference_flat_multimap.cpp',
'test_reference_flat_multiset.cpp',
'test_reference_flat_set.cpp',
'test_rescale.cpp',
'test_result.cpp',
'test_rms.cpp',
'test_scaled_rounding.cpp',
'test_set.cpp',
'test_shared_message.cpp',
'test_smallest.cpp',
'test_span.cpp',
'test_stack.cpp',
'test_standard_deviation.cpp',
'test_state_chart.cpp',
'test_state_chart_with_data_parameter.cpp',
'test_state_chart_with_rvalue_data_parameter.cpp',
'test_string_char.cpp',
'test_string_char_external_buffer.cpp',
'test_string_stream.cpp',
'test_string_stream_u16.cpp',
'test_string_stream_u32.cpp',
'test_string_stream_wchar_t.cpp',
'test_string_u16.cpp',
'test_string_u16_external_buffer.cpp',
'test_string_u32.cpp',
'test_string_u32_external_buffer.cpp',
'test_string_utilities.cpp',
'test_string_utilities_std.cpp',
'test_string_utilities_std_u16.cpp',
'test_string_utilities_std_u32.cpp',
'test_string_utilities_std_wchar_t.cpp',
'test_string_utilities_u16.cpp',
'test_string_utilities_u32.cpp',
'test_string_utilities_wchar_t.cpp',
'test_string_view.cpp',
'test_string_wchar_t.cpp',
'test_string_wchar_t_external_buffer.cpp',
'test_task_scheduler.cpp',
'test_threshold.cpp',
'test_to_string.cpp',
'test_to_u16string.cpp',
'test_to_u32string.cpp',
'test_to_wstring.cpp',
'test_type_def.cpp',
'test_type_lookup.cpp',
'test_type_select.cpp',
'test_type_traits.cpp',
'test_unordered_map.cpp',
'test_unordered_multimap.cpp',
'test_unordered_multiset.cpp',
'test_unordered_set.cpp',
'test_user_type.cpp',
'test_utility.cpp',
'test_variance.cpp',
'test_variant_legacy.cpp',
'test_variant_pool.cpp',
'test_variant_pool_external_buffer.cpp',
'test_variant_variadic.cpp',
'test_vector.cpp',
'test_vector_external_buffer.cpp',
'test_vector_non_trivial.cpp',
'test_vector_pointer.cpp',
'test_vector_pointer_external_buffer.cpp',
'test_visitor.cpp',
'test_xor_checksum.cpp',
'test_xor_rotate_checksum.cpp',
'test_message_broker.cpp',
'test_message_bus.cpp',
'test_message_packet.cpp',
'test_message_router.cpp',
'test_message_router_registry.cpp',
'test_message_timer.cpp',
'test_message_timer_atomic.cpp',
'test_message_timer_interrupt.cpp',
'test_message_timer_locked.cpp',
'test_multimap.cpp',
'test_multiset.cpp',
'test_multi_array.cpp',
'test_multi_range.cpp',
'test_multi_vector.cpp',
'test_murmur3.cpp',
'test_nth_type.cpp',
'test_numeric.cpp',
'test_observer.cpp',
'test_optional.cpp',
'test_packet.cpp',
'test_parameter_pack.cpp',
'test_parameter_type.cpp',
'test_parity_checksum.cpp',
'test_pearson.cpp',
'test_poly_span_dynamic_extent.cpp',
'test_poly_span_fixed_extent.cpp',
'test_pool.cpp',
'test_pool_external_buffer.cpp',
'test_priority_queue.cpp',
'test_pseudo_moving_average.cpp',
'test_quantize.cpp',
'test_queue.cpp',
'test_queue_lockable.cpp',
'test_queue_lockable_small.cpp',
'test_queue_memory_model_small.cpp',
'test_queue_mpmc_mutex.cpp',
'test_queue_mpmc_mutex_small.cpp',
'test_queue_spsc_atomic.cpp',
'test_queue_spsc_atomic_small.cpp',
'test_queue_spsc_isr.cpp',
'test_queue_spsc_isr_small.cpp',
'test_queue_spsc_locked.cpp',
'test_queue_spsc_locked_small.cpp',
'test_random.cpp',
'test_reference_flat_map.cpp',
'test_reference_flat_multimap.cpp',
'test_reference_flat_multiset.cpp',
'test_reference_flat_set.cpp',
'test_rescale.cpp',
'test_rms.cpp',
'test_scaled_rounding.cpp',
'test_set.cpp',
'test_shared_message.cpp',
'test_singleton.cpp',
'test_smallest.cpp',
'test_span_dynamic_extent.cpp',
'test_span_fixed_extent.cpp',
'test_stack.cpp',
'test_standard_deviation.cpp',
'test_state_chart.cpp',
'test_state_chart_with_data_parameter.cpp',
'test_state_chart_with_rvalue_data_parameter.cpp',
'test_state_chart_compile_time.cpp',
'test_state_chart_compile_time_with_data_parameter.cpp',
'test_string_char.cpp',
'test_string_char_external_buffer.cpp',
'test_string_stream.cpp',
'test_string_stream_u16.cpp',
'test_string_stream_u32.cpp',
'test_string_stream_wchar_t.cpp',
'test_string_u16.cpp',
'test_string_u16_external_buffer.cpp',
'test_string_u32.cpp',
'test_string_u32_external_buffer.cpp',
'test_string_utilities.cpp',
'test_string_utilities_std.cpp',
'test_string_utilities_std_u16.cpp',
'test_string_utilities_std_u32.cpp',
'test_string_utilities_std_wchar_t.cpp',
'test_string_utilities_u16.cpp',
'test_string_utilities_u32.cpp',
'test_string_utilities_wchar_t.cpp',
'test_string_view.cpp',
'test_string_wchar_t.cpp',
'test_string_wchar_t_external_buffer.cpp',
'test_successor.cpp',
'test_task_scheduler.cpp',
'test_threshold.cpp',
'test_to_string.cpp',
'test_to_u16string.cpp',
'test_to_u32string.cpp',
'test_to_wstring.cpp',
'test_type_def.cpp',
'test_type_lookup.cpp',
'test_type_select.cpp',
'test_type_traits.cpp',
'test_unaligned_type.cpp',
'test_unaligned_type_constexpr.cpp',
'test_unordered_map.cpp',
'test_unordered_multimap.cpp',
'test_unordered_multiset.cpp',
'test_unordered_set.cpp',
'test_user_type.cpp',
'test_utility.cpp',
'test_variance.cpp',
'test_variant_legacy.cpp',
'test_variant_variadic.cpp',
'test_variant_pool.cpp',
'test_variant_pool_external_buffer.cpp',
'test_vector.cpp',
'test_vector_external_buffer.cpp',
'test_vector_non_trivial.cpp',
'test_vector_pointer.cpp',
'test_vector_pointer_external_buffer.cpp',
'test_visitor.cpp',
'test_xor_checksum.cpp',
'test_xor_rotate_checksum.cpp'
)
compile_args = [
'-DENABLE_ETL_UNIT_TESTS',
'-DETL_DEBUG',
]
link_args = []
if get_option('use_stl')
compile_args += '-DETL_NO_STL=0'
@ -249,9 +274,14 @@ elif
compile_args += '-DETL_NO_STL=1'
endif
if meson.get_compiler('cpp').get_id() == 'gcc'
etl_test_sources += files('test_atomic_gcc_sync.cpp')
if meson.get_compiler('cpp').get_argument_syntax() == 'gcc'
compile_args += '-fsanitize=address,undefined'
compile_args += '-fexceptions'
compile_args += '-Wall'
compile_args += '-Wextra'
compile_args += '-Wno-non-virtual-dtor' #TODO remove and fix warning in code
compile_args += '-Werror'
link_args += '-fsanitize=address,undefined'
endif
threads_dep = dependency('threads')
@ -264,4 +294,7 @@ etl_unit_tests = executable('etl_unit_tests',
sources: etl_test_sources,
dependencies: [etl_dep, unittestcpp_dep, threads_dep],
cpp_args: compile_args,
link_args: link_args,
)
test('etl_unit_tests', etl_unit_tests)

View File

@ -1246,6 +1246,22 @@ namespace
CHECK_EQUAL(etl::ibitset::npos, bits24.find_next(true, 13));
}
//*************************************************************************
TEST(test_find_next_github_issue_617)
{
etl::bitset<64> bs1(0xC000'0000'0000'0031ULL);
size_t bs1fnt1 = bs1.find_next(true, 10);
size_t bs1fnt2 = bs1.find_next(true, 59);
CHECK_EQUAL(62U, bs1fnt1);
CHECK_EQUAL(62U, bs1fnt2);
etl::bitset<64> bs2(0x3FFF'FFFF'FFFF'FFCEULL);
size_t bs2fnf1 = bs2.find_next(false, 10);
size_t bs2fnf2 = bs2.find_next(false, 59);
CHECK_EQUAL(62U, bs2fnf1);
CHECK_EQUAL(62U, bs2fnf2);
}
//*************************************************************************
TEST(test_swap)
{

View File

@ -1952,6 +1952,28 @@ namespace
CHECK_EQUAL(4U, bs4fnt1);
}
//*************************************************************************
TEST(test_find_next_github_issue_617)
{
constexpr etl::bitset<64> bs1(ull(0xC000'0000'0000'0031));
constexpr size_t bs1fnt1 = bs1.find_next(true, 10);
constexpr size_t bs1fnt2 = bs1.find_next(true, 59);
CHECK_EQUAL(62U, bs1fnt1);
CHECK_EQUAL(62U, bs1fnt2);
constexpr etl::bitset<64> bs2(ull(0x3FFF'FFFF'FFFF'FFCE));
constexpr size_t bs2fnf1 = bs2.find_next(false, 10);
constexpr size_t bs2fnf2 = bs2.find_next(false, 59);
CHECK_EQUAL(62U, bs2fnf1);
CHECK_EQUAL(62U, bs2fnf2);
constexpr etl::bitset<64, uint32_t> bs32(ull(0xC000'0000'0000'0031));
constexpr size_t bs32fnt1 = bs32.find_next(true, 10);
constexpr size_t bs32fnt2 = bs32.find_next(true, 59);
CHECK_EQUAL(62U, bs32fnt1);
CHECK_EQUAL(62U, bs32fnt2);
}
//*************************************************************************
//*************************************************************************
TEST(test_swap)

View File

@ -1796,6 +1796,25 @@ namespace
CHECK_EQUAL(4U, bs4fnt1);
}
//*************************************************************************
TEST(test_find_next_github_issue_617)
{
etl::bitset_ext<64>::element_type buffer1[etl::bitset_ext<64>::Number_Of_Elements];
etl::bitset_ext<64>::element_type buffer2[etl::bitset_ext<64>::Number_Of_Elements];
etl::bitset_ext<64> bs1(ull(0xC000'0000'0000'0031), buffer1);
size_t bs1fnt1 = bs1.find_next(true, 10);
size_t bs1fnt2 = bs1.find_next(true, 59);
CHECK_EQUAL(62U, bs1fnt1);
CHECK_EQUAL(62U, bs1fnt2);
etl::bitset_ext<64> bs2(ull(0x3FFF'FFFF'FFFF'FFCE), buffer2);
size_t bs2fnf1 = bs2.find_next(false, 10);
size_t bs2fnf2 = bs2.find_next(false, 59);
CHECK_EQUAL(62U, bs2fnf1);
CHECK_EQUAL(62U, bs2fnf2);
}
//*************************************************************************
TEST(test_swap)
{

View File

@ -199,6 +199,30 @@ namespace
}
}
TEST(test_hash_floating_point_negative_zero)
{
if (sizeof(float) == sizeof(size_t)) {
etl::hash<float> hasher{};
size_t hash1 = hasher(0.0);
size_t hash2 = hasher(-0.0);
CHECK_EQUAL(hash1, hash2);
}
if (sizeof(double) == sizeof(size_t)) {
etl::hash<double> hasher{};
size_t hash1 = hasher(0.0);
size_t hash2 = hasher(-0.0);
CHECK_EQUAL(hash1, hash2);
}
if (sizeof(long double) == sizeof(size_t)) {
etl::hash<long double> hasher{};
size_t hash1 = hasher(0.0);
size_t hash2 = hasher(-0.0);
CHECK_EQUAL(hash1, hash2);
}
}
//*************************************************************************
TEST(test_hash_pointer)
{
@ -231,10 +255,13 @@ namespace
//*************************************************************************
TEST(test_hash_enums)
{
enum class MyEnumClass : char {
enum class MyEnumClass : char
{
OneE = 0x1E
};
enum MyEnum : char {
enum MyEnum : char
{
MyEnum_TwoF = 0x2F
};
@ -245,17 +272,23 @@ namespace
CHECK_EQUAL(0x2F, hash);
}
TEST(test_hash_big_enums) {
//*************************************************************************
TEST(test_hash_big_enums)
{
constexpr unsigned long long big_number = 0x5AA555AA3CC333CCULL;
enum class MyBigEnumClass : unsigned long long {
enum class MyBigEnumClass : unsigned long long
{
Big = big_number
};
size_t hash = etl::hash<MyBigEnumClass>()(MyBigEnumClass::Big);
size_t expectedHash = etl::hash<unsigned long long>()(big_number);
CHECK_EQUAL(expectedHash, hash);
}
TEST(test_hash_poisoned) {
//*************************************************************************
TEST(test_hash_poisoned)
{
// Unspecialized hash<> should be disabled (unusable) - see https://en.cppreference.com/w/cpp/utility/hash
class A {};
typedef etl::hash<A> general_hasher;
@ -267,8 +300,9 @@ namespace
CHECK_FALSE(std::is_move_assignable<general_hasher>::value);
}
TEST(test_hash_custom) {
//*************************************************************************
TEST(test_hash_custom)
{
typedef etl::hash<CustomType> custom_hasher;
CHECK_TRUE(std::is_default_constructible<custom_hasher>::value);

View File

@ -29,6 +29,8 @@ SOFTWARE.
#include "unit_test_framework.h"
#include <string>
#include <list>
#include <algorithm>
#include "etl/iterator.h"
@ -276,7 +278,7 @@ namespace
CHECK_EQUAL(*sri, *eri);
}
//*************************************************************************
TEST(test_input)
{
CHECK(!!etl::is_input_iterator<input>::value);
@ -292,6 +294,7 @@ namespace
CHECK(!etl::is_random_iterator_concept<input>::value);
}
//*************************************************************************
TEST(test_output)
{
CHECK(!etl::is_input_iterator<output>::value);
@ -307,6 +310,7 @@ namespace
CHECK(!etl::is_random_iterator_concept<output>::value);
}
//*************************************************************************
TEST(test_forward)
{
CHECK(!etl::is_input_iterator<forward>::value);
@ -322,6 +326,7 @@ namespace
CHECK(!etl::is_random_iterator_concept<forward>::value);
}
//*************************************************************************
TEST(test_bidirectional)
{
CHECK(!etl::is_input_iterator<bidirectional>::value);
@ -337,6 +342,7 @@ namespace
CHECK(!etl::is_random_iterator_concept<bidirectional>::value);
}
//*************************************************************************
TEST(test_random)
{
CHECK(!etl::is_input_iterator<random>::value);
@ -352,6 +358,7 @@ namespace
CHECK(!!etl::is_random_iterator_concept<random>::value);
}
//*************************************************************************
TEST(test_pointer)
{
CHECK(!etl::is_input_iterator<pointer>::value);
@ -367,6 +374,7 @@ namespace
CHECK(!!etl::is_random_iterator_concept<pointer>::value);
}
//*************************************************************************
TEST(test_const_pointer)
{
CHECK(!etl::is_input_iterator<const_pointer>::value);
@ -383,7 +391,7 @@ namespace
}
//*************************************************************************
TEST(move_iterator_constructors)
TEST(test_move_iterator_constructors)
{
Item list[] = { Item("1"), Item("2"), Item("3") };
@ -402,7 +410,7 @@ namespace
}
//*************************************************************************
TEST(move_iterator_relational_operators)
TEST(test_move_iterator_relational_operators)
{
Item list[] = { Item("1"), Item("2"), Item("3") };
@ -434,7 +442,7 @@ namespace
}
//*************************************************************************
TEST(move_iterator_access_operators)
TEST(test_move_iterator_access_operators)
{
Item item1("1");
@ -455,7 +463,7 @@ namespace
}
//*************************************************************************
TEST(move_iterator_index)
TEST(test_move_iterator_index)
{
Item list[] = { Item("1"), Item("2"), Item("3") };
@ -466,7 +474,7 @@ namespace
}
//*************************************************************************
TEST(move_iterator_increment_decrement)
TEST(test_move_iterator_increment_decrement)
{
Item list[] = { Item("1"), Item("2"), Item("3") };
@ -506,7 +514,7 @@ namespace
}
//*************************************************************************
TEST(move_iterator_subtraction)
TEST(test_move_iterator_subtraction)
{
Item list[] = { Item("1"), Item("2"), Item("3") };
@ -517,5 +525,41 @@ namespace
CHECK_EQUAL(1, d);
}
//*************************************************************************
TEST(test_front_insert_iterator)
{
std::list<int> input = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::list<int> expected = { 81, 64, 49, 36, 25, 16, 9, 4, 1, 0 };
std::list<int> output;
auto squared = [](int value)
{
return value * value;
};
std::transform(input.cbegin(), input.cend(), etl::front_inserter(output), squared);
CHECK_EQUAL(expected.size(), output.size());
CHECK(std::equal(output.begin(), output.end(), expected.begin()));
}
//*************************************************************************
TEST(test_back_insert_iterator)
{
std::list<int> input = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::list<int> expected = { 0, 1, 4, 9, 16, 25, 36, 49, 64, 81 };
std::list<int> output;
auto squared = [](int value)
{
return value * value;
};
std::transform(input.cbegin(), input.cend(), etl::back_inserter(output), squared);
CHECK_EQUAL(expected.size(), output.size());
CHECK(std::equal(output.begin(), output.end(), expected.begin()));
}
};
}

View File

@ -301,6 +301,28 @@ namespace
CHECK(are_equal);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_front_insert_iterator)
{
DataInt data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
DataInt expected = {81, 64, 49, 36, 25, 16, 9, 4, 1, 0};
DataInt transformed;
auto squared = [](int value)
{
return value * value;
};
etl::transform(data.cbegin(), data.cend(), etl::front_inserter(transformed), squared);
CHECK_EQUAL(expected.size(), transformed.size());
bool transformed_equals_expected = std::equal(transformed.begin(),
transformed.end(),
expected.begin());
CHECK(transformed_equals_expected);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_resize_up)
{

View File

@ -760,5 +760,23 @@ namespace
CHECK_EQUAL(0x1234, test_le.value());
CHECK_EQUAL(0x1234, test_be.value());
}
//*************************************************************************
TEST(test_storage_bytes)
{
etl::le_uint16_t test_le(0x1234);
etl::be_uint16_t test_be(0x1234);
int lev0 = test_le[0];
int lev1 = test_le[1];
int bev0 = test_be[0];
int bev1 = test_be[1];
CHECK_EQUAL(0x34, lev0);
CHECK_EQUAL(0x12, lev1);
CHECK_EQUAL(0x12, bev0);
CHECK_EQUAL(0x34, bev1);
}
};
}

View File

@ -544,8 +544,8 @@ namespace
{
static constexpr etl::be_uint16_t test(0x1234);
constexpr const char* p1 = test.data();
constexpr const char* p2 = test.data() + 1U;
constexpr etl::be_uint16_t::const_pointer p1 = test.data();
constexpr etl::be_uint16_t::const_pointer p2 = test.data() + 1U;
CHECK_EQUAL(0x12, *p1);
CHECK_EQUAL(0x34, *p2);
@ -618,5 +618,23 @@ namespace
CHECK_EQUAL(0x1234, lev);
CHECK_EQUAL(0x1234, bev);
}
//*************************************************************************
TEST(test_storage_bytes)
{
constexpr etl::le_uint16_t test_le(0x1234);
constexpr etl::be_uint16_t test_be(0x1234);
constexpr int lev0 = test_le[0];
constexpr int lev1 = test_le[1];
constexpr int bev0 = test_be[0];
constexpr int bev1 = test_be[1];
CHECK_EQUAL(0x34, lev0);
CHECK_EQUAL(0x12, lev1);
CHECK_EQUAL(0x12, bev0);
CHECK_EQUAL(0x34, bev1);
}
};
}

View File

@ -969,11 +969,11 @@ namespace
{17, "17"}, {14, "14"}, { 3, "3"}, { 7, "7"}, { 2, "2"},
{ 6, "6"}, { 9, "9"}, { 3, "3"}, {18, "18"}, {10, "10"},
{ 8, "8"}, {11, "11"}, { 4, "4"}, { 1, "1"}, {12, "12"},
{15, "15"}, {16, "16"}, { 0, "0"}, { 5, "5"}, {19, "19"}
{15, "15"}, {16, "16"}, { 0, "0"}, { 5, "5"}, {19, "19"}
};
std::vector<etl_map::value_type> random_keys2 =
{
{
{ 3, "3"}, { 6, "6"}, { 5, "5"}, {17, "17"}, { 2, "2"},
{ 7, "7"}, { 3, "3"}, {19, "19"}, { 8, "8"}, {15, "15"},
{14, "14"}, { 0, "0"}, {18, "18"}, { 4, "4"}, {10, "10"},
@ -1051,7 +1051,7 @@ namespace
}
//*************************************************************************
TEST(test_ndc_hasher_and_key_eq)
TEST(test_ndc_hasher_and_key_eq)
{
typedef etl::unordered_map<size_t, int, 10, 10, ndc_hash, ndc_key_eq> Map;
ndc_hash hasher1(1);
@ -1093,7 +1093,7 @@ namespace
}
//*************************************************************************
TEST(test_parameterized_eq)
TEST(test_parameterized_eq)
{
constexpr std::size_t MODULO = 4;
parameterized_hash hash{MODULO};
@ -1108,12 +1108,14 @@ namespace
CHECK_EQUAL(map.at(10), 3);
CHECK_EQUAL(constmap.at(10), 3);
CHECK_FALSE(map.insert(etl::make_pair(6, 7)).second);
const std::pair<const std::size_t, int> keyvaluepair{6, 7};
CHECK_FALSE(map.insert(keyvaluepair).second);
CHECK_FALSE(map.insert(std::move(keyvaluepair)).second);
CHECK(map.find(14) != map.end());
CHECK(constmap.find(14) != constmap.end());
map.erase(2);
map.erase(14);
CHECK(map.find(6) == map.end());
}
@ -1155,13 +1157,13 @@ namespace
CustomKeyEq ceq2(2);
using value_type = etl::unordered_map<uint32_t, uint32_t, 5, 5, CustomHashFunction, CustomKeyEq>::value_type;
std::array<value_type, 5> data =
{
value_type{1, 11},
value_type{2, 22},
value_type{3, 33},
value_type{4, 44},
value_type{5, 55}
std::array<value_type, 5> data =
{
value_type{1, 11},
value_type{2, 22},
value_type{3, 33},
value_type{4, 44},
value_type{5, 55}
};
etl::unordered_map<uint32_t, uint32_t, 5, 5, CustomHashFunction, CustomKeyEq> map1(data.begin(), data.end(), chf1, ceq2);

View File

@ -133,6 +133,35 @@ namespace
int id;
};
//*************************************************************************
// Hasher whose hash behaviour depends on provided data.
struct parameterized_hash
{
size_t modulus;
parameterized_hash(size_t modulus_ = 2) : modulus(modulus_){}
size_t operator()(size_t val) const
{
return val % modulus;
}
};
//*************************************************************************
// Equality checker whose behaviour depends on provided data.
struct parameterized_equal
{
size_t modulus;
// Hasher whose hash behaviour depends on provided data.
parameterized_equal(size_t modulus_ = 2) : modulus(modulus_){}
bool operator()(size_t lhs, size_t rhs) const
{
return (lhs % modulus) == (rhs % modulus);
}
};
SUITE(test_unordered_multimap)
{
static const size_t SIZE = 10;
@ -362,9 +391,9 @@ namespace
DataNDC data(initial_data.begin(), initial_data.end());
DataNDC other_data(data);
#include "etl/private/diagnostic_self_assign_overloaded_push.h"
#include "etl/private/diagnostic_self_assign_overloaded_push.h"
other_data = other_data;
#include "etl/private/diagnostic_pop.h"
#include "etl/private/diagnostic_pop.h"
CHECK(data == other_data);
}
@ -999,5 +1028,29 @@ namespace
using Map = etl::unordered_multimap<int, int, 1, 1>;
CHECK((!std::is_same_v<typename Map::const_iterator::value_type, typename Map::iterator::value_type>));
}
TEST(test_parameterized_eq)
{
constexpr std::size_t MODULO = 4;
parameterized_hash hash{MODULO};
parameterized_equal eq{MODULO};
// values are equal modulo 4
etl::unordered_multimap<std::size_t, int, 10, 10, parameterized_hash, parameterized_equal> map;
map.insert(etl::make_pair(2, 20));
map.insert(etl::make_pair(6, 21));
map.insert(etl::make_pair(10, 22));
const auto& constmap = map;
CHECK_EQUAL(constmap.count(6), 3);
{
auto range = map.equal_range(6);
CHECK_EQUAL(std::distance(range.first, range.second), 3);
}
{
auto range = constmap.equal_range(6);
CHECK_EQUAL(std::distance(range.first, range.second), 3);
}
}
};
}

View File

@ -106,6 +106,35 @@ namespace
int id;
};
//*************************************************************************
// Hasher whose hash behaviour depends on provided data.
struct parameterized_hash
{
size_t modulus;
parameterized_hash(size_t modulus_ = 2) : modulus(modulus_){}
size_t operator()(size_t val) const
{
return val % modulus;
}
};
//*************************************************************************
// Equality checker whose behaviour depends on provided data.
struct parameterized_equal
{
size_t modulus;
// Hasher whose hash behaviour depends on provided data.
parameterized_equal(size_t modulus_ = 2) : modulus(modulus_){}
bool operator()(size_t lhs, size_t rhs) const
{
return (lhs % modulus) == (rhs % modulus);
}
};
SUITE(test_unordered_multiset)
{
static const size_t SIZE = 10;
@ -306,9 +335,9 @@ namespace
DataNDC data(initial_data.begin(), initial_data.end());
DataNDC other_data(data);
#include "etl/private/diagnostic_self_assign_overloaded_push.h"
#include "etl/private/diagnostic_self_assign_overloaded_push.h"
other_data = other_data;
#include "etl/private/diagnostic_pop.h"
#include "etl/private/diagnostic_pop.h"
CHECK(data == other_data);
}
@ -875,5 +904,29 @@ namespace
using Set = etl::unordered_multiset<int, 1, 1>;
CHECK((!std::is_same_v<typename Set::const_iterator::value_type, typename Set::iterator::value_type>));
}
TEST(test_parameterized_eq)
{
constexpr std::size_t MODULO = 4;
parameterized_hash hash{MODULO};
parameterized_equal eq{MODULO};
// values are equal modulo 4
etl::unordered_multiset<std::size_t, 10, 10, parameterized_hash, parameterized_equal> set;
set.insert(2);
set.insert(6);
set.insert(10);
const auto& constset = set;
CHECK_EQUAL(constset.count(6), 3);
{
auto range = set.equal_range(6);
CHECK_EQUAL(std::distance(range.first, range.second), 3);
}
{
auto range = constset.equal_range(6);
CHECK_EQUAL(std::distance(range.first, range.second), 3);
}
}
};
}

View File

@ -106,6 +106,35 @@ namespace
int id;
};
//*************************************************************************
// Hasher whose hash behaviour depends on provided data.
struct parameterized_hash
{
size_t modulus;
parameterized_hash(size_t modulus_ = 2) : modulus(modulus_){}
size_t operator()(size_t val) const
{
return val % modulus;
}
};
//*************************************************************************
// Equality checker whose behaviour depends on provided data.
struct parameterized_equal
{
size_t modulus;
// Hasher whose hash behaviour depends on provided data.
parameterized_equal(size_t modulus_ = 2) : modulus(modulus_){}
bool operator()(size_t lhs, size_t rhs) const
{
return (lhs % modulus) == (rhs % modulus);
}
};
//***************************************************************************
SUITE(test_unordered_set)
{
@ -290,9 +319,9 @@ namespace
DataNDC data(initial_data.begin(), initial_data.end());
DataNDC other_data(data);
#include "etl/private/diagnostic_self_assign_overloaded_push.h"
#include "etl/private/diagnostic_self_assign_overloaded_push.h"
other_data = other_data;
#include "etl/private/diagnostic_pop.h"
#include "etl/private/diagnostic_pop.h"
CHECK(data == other_data);
}
@ -696,18 +725,40 @@ namespace
CHECK_EQUAL("set = 3", s[1]);
}
TEST(test_parameterized_eq)
{
constexpr std::size_t MODULO = 4;
parameterized_hash hash{MODULO};
parameterized_equal eq{MODULO};
// values are equal modulo 4
etl::unordered_set<std::size_t, 10, 10, parameterized_hash, parameterized_equal> set;
set.insert(2);
const auto& constset = set;
const size_t key = 6;
CHECK_FALSE(set.insert(key).second);
CHECK_FALSE(set.insert(std::move(key)).second);
CHECK(set.find(14) != set.end());
CHECK(constset.find(14) != constset.end());
set.erase(14);
CHECK(set.find(6) == set.end());
}
//*************************************************************************
TEST(test_equality_comparison_fails_when_hash_collisions_occur_582)
{
struct bad_hash
{
// Force hash collisions
size_t operator()(int key) const
{
return key % 4;
size_t operator()(int key) const
{
return key % 4;
}
};
std::vector<int> random_keys1 = { 17, 14, 3, 7, 2, 6, 9, 3, 18, 10, 8, 11, 4, 1, 12, 15, 16, 0, 5, 19 };
std::vector<int> random_keys2 = { 3, 6, 5, 17, 2, 7, 3, 19, 8, 15, 14, 0, 18, 4, 10, 9, 16, 11, 12, 1 };
@ -748,7 +799,7 @@ namespace
//***************************************************
CHECK_EQUAL((stdset1 == stdset2), (etlset1 == etlset2));
}
//*************************************************************************
TEST(test_copying_of_hash_and_key_compare_with_copy_construct)
{
@ -773,7 +824,7 @@ namespace
etl::unordered_set<uint32_t, 5, 5, CustomHashFunction, CustomKeyEq> set1(chf1, ceq2);
etl::unordered_set<uint32_t, 5, 5, CustomHashFunction, CustomKeyEq> set2(chf3, ceq4);
set2.operator=(set1);
CHECK_EQUAL(chf1.id, set2.hash_function().id);

View File

@ -30,6 +30,10 @@ SOFTWARE.
#include "etl/utility.h"
#include <map>
#include <vector>
#include <algorithm>
#include "data.h"
namespace
@ -330,6 +334,80 @@ namespace
CHECK(constCalled);
}
//*************************************************************************
TEST(test_select1st)
{
typedef etl::pair<int, std::string> EtlPair;
typedef std::pair<int, std::string> StdPair;
EtlPair ep1(1, "Hello");
StdPair sp2(2, "World");
auto selector = etl::select1st<EtlPair>();
CHECK_EQUAL(1, selector(ep1));
CHECK_EQUAL(2, selector(sp2));
}
//*************************************************************************
TEST(test_select1st_example)
{
//! [test_select1st_example]
using Map = std::map<int, double>;
using Vector = std::vector<int>;
const Map map = {{1, 0.3},
{47, 0.8},
{33, 0.1}};
Vector result{};
// Extract the map keys into a vector
std::transform(map.begin(), map.end(), std::back_inserter(result), etl::select1st<Map::value_type>());
//! [test_select1st_example]
CHECK_EQUAL(3, result.size());
const Vector expected{1, 33, 47};
CHECK_ARRAY_EQUAL(expected, result, 3);
}
//*************************************************************************
TEST(test_select2nd)
{
typedef etl::pair<int, std::string> EtlPair;
typedef std::pair<int, std::string> StdPair;
EtlPair ep1(1, "Hello");
StdPair sp2(2, "World");
auto selector = etl::select2nd<EtlPair>();
CHECK_EQUAL(std::string("Hello"), selector(ep1));
CHECK_EQUAL(std::string("World"), selector(sp2));
}
//*************************************************************************
TEST(test_select2nd_example)
{
//! [test_select2nd_example]
using Map = std::map<int, double>;
using Vector = std::vector<double>;
const Map map = {{1, 0.3},
{47, 0.8},
{33, 0.1}};
Vector result{};
// Extract the map values into a vector
std::transform(map.begin(), map.end(), std::back_inserter(result), etl::select2nd<Map::value_type>());
//! [test_select2nd_example]
CHECK_EQUAL(3, result.size());
const Vector expected{0.1, 0.3, 0.8};
sort(result.begin(), result.end()); // sort for comparison
CHECK_ARRAY_CLOSE(expected, result, 3, 0.0001);
}
//*************************************************************************
TEST(test_functor)
{

View File

@ -12216,6 +12216,7 @@
<None Include="..\..\README.md" />
<None Include="..\..\scripts\generator_test.py" />
<None Include="..\..\scripts\update_release.py" />
<None Include="..\meson.build" />
<None Include="..\runsanitychecks.sh" />
<None Include="..\runtests.sh" />
<None Include="cpp.hint" />

View File

@ -3481,6 +3481,9 @@
<None Include="..\..\scripts\generator_test.py">
<Filter>Tests\Scripts</Filter>
</None>
<None Include="..\meson.build">
<Filter>Tests\Test Support</Filter>
</None>
</ItemGroup>
<ItemGroup>
<Text Include="..\..\support\Release notes.txt">

139
test/vs2022/etl.sln Normal file
View File

@ -0,0 +1,139 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.3.32922.545
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "etl", "etl.vcxproj", "{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug Intel - No STL|Win32 = Debug Intel - No STL|Win32
Debug Intel - No STL|x64 = Debug Intel - No STL|x64
Debug Intel|Win32 = Debug Intel|Win32
Debug Intel|x64 = Debug Intel|x64
Debug LLVM - No STL - Force Built-ins|Win32 = Debug LLVM - No STL - Force Built-ins|Win32
Debug LLVM - No STL - Force Built-ins|x64 = Debug LLVM - No STL - Force Built-ins|x64
Debug LLVM - No STL|Win32 = Debug LLVM - No STL|Win32
Debug LLVM - No STL|x64 = Debug LLVM - No STL|x64
Debug LLVM|Win32 = Debug LLVM|Win32
Debug LLVM|x64 = Debug LLVM|x64
Debug MSVC - Force C++03|Win32 = Debug MSVC - Force C++03|Win32
Debug MSVC - Force C++03|x64 = Debug MSVC - Force C++03|x64
Debug MSVC - No STL - Auto Built-ins|Win32 = Debug MSVC - No STL - Auto Built-ins|Win32
Debug MSVC - No STL - Auto Built-ins|x64 = Debug MSVC - No STL - Auto Built-ins|x64
Debug MSVC - No STL - Force Built-ins|Win32 = Debug MSVC - No STL - Force Built-ins|Win32
Debug MSVC - No STL - Force Built-ins|x64 = Debug MSVC - No STL - Force Built-ins|x64
Debug MSVC - No STL|Win32 = Debug MSVC - No STL|Win32
Debug MSVC - No STL|x64 = Debug MSVC - No STL|x64
Debug MSVC - No Tests|Win32 = Debug MSVC - No Tests|Win32
Debug MSVC - No Tests|x64 = Debug MSVC - No Tests|x64
Debug MSVC - Small Strings|Win32 = Debug MSVC - Small Strings|Win32
Debug MSVC - Small Strings|x64 = Debug MSVC - Small Strings|x64
Debug MSVC - String Truncation Is Error|Win32 = Debug MSVC - String Truncation Is Error|Win32
Debug MSVC - String Truncation Is Error|x64 = Debug MSVC - String Truncation Is Error|x64
Debug MSVC 64|Win32 = Debug MSVC 64|Win32
Debug MSVC 64|x64 = Debug MSVC 64|x64
Debug MSVC C++20 - No STL|Win32 = Debug MSVC C++20 - No STL|Win32
Debug MSVC C++20 - No STL|x64 = Debug MSVC C++20 - No STL|x64
Debug MSVC C++20|Win32 = Debug MSVC C++20|Win32
Debug MSVC C++20|x64 = Debug MSVC C++20|x64
Debug MSVC|Win32 = Debug MSVC|Win32
Debug MSVC|x64 = Debug MSVC|x64
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
MSVC Debug Appveyor|Win32 = MSVC Debug Appveyor|Win32
MSVC Debug Appveyor|x64 = MSVC Debug Appveyor|x64
MSVC Debug No STL Appveyor|Win32 = MSVC Debug No STL Appveyor|Win32
MSVC Debug No STL Appveyor|x64 = MSVC Debug No STL Appveyor|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug Intel - No STL|Win32.ActiveCfg = Debug Intel - No STL|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug Intel - No STL|Win32.Build.0 = Debug Intel - No STL|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug Intel - No STL|x64.ActiveCfg = Debug Intel - No STL|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug Intel - No STL|x64.Build.0 = Debug Intel - No STL|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug Intel|Win32.ActiveCfg = Debug Intel|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug Intel|Win32.Build.0 = Debug Intel|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug Intel|x64.ActiveCfg = Debug Intel|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug Intel|x64.Build.0 = Debug Intel|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug LLVM - No STL - Force Built-ins|Win32.ActiveCfg = Debug|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug LLVM - No STL - Force Built-ins|Win32.Build.0 = Debug|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug LLVM - No STL - Force Built-ins|x64.ActiveCfg = Test2|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug LLVM - No STL - Force Built-ins|x64.Build.0 = Test2|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug LLVM - No STL|Win32.ActiveCfg = Debug LLVM - No STL|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug LLVM - No STL|Win32.Build.0 = Debug LLVM - No STL|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug LLVM - No STL|x64.ActiveCfg = DebugLLVMNoSTL|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug LLVM - No STL|x64.Build.0 = DebugLLVMNoSTL|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug LLVM|Win32.ActiveCfg = Debug LLVM|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug LLVM|Win32.Build.0 = Debug LLVM|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug LLVM|x64.ActiveCfg = Debug LLVM|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug LLVM|x64.Build.0 = Debug LLVM|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC - Force C++03|Win32.ActiveCfg = Debug MSVC - Force C++03|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC - Force C++03|Win32.Build.0 = Debug MSVC - Force C++03|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC - Force C++03|x64.ActiveCfg = Debug MSVC - Force C++03|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC - Force C++03|x64.Build.0 = Debug MSVC - Force C++03|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC - No STL - Auto Built-ins|Win32.ActiveCfg = Debug MSVC - No STL - Built-ins|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC - No STL - Auto Built-ins|Win32.Build.0 = Debug MSVC - No STL - Built-ins|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC - No STL - Auto Built-ins|x64.ActiveCfg = Test1|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC - No STL - Auto Built-ins|x64.Build.0 = Test1|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC - No STL - Force Built-ins|Win32.ActiveCfg = Debug MSVC - No STL - Force Built-ins|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC - No STL - Force Built-ins|Win32.Build.0 = Debug MSVC - No STL - Force Built-ins|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC - No STL - Force Built-ins|x64.ActiveCfg = Debug MSVC - No STL - Force Built-ins|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC - No STL - Force Built-ins|x64.Build.0 = Debug MSVC - No STL - Force Built-ins|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC - No STL|Win32.ActiveCfg = Debug - No STL|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC - No STL|Win32.Build.0 = Debug - No STL|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC - No STL|x64.ActiveCfg = DebugNoSTL|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC - No STL|x64.Build.0 = DebugNoSTL|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC - No Tests|Win32.ActiveCfg = Debug MSVC - No Tests|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC - No Tests|Win32.Build.0 = Debug MSVC - No Tests|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC - No Tests|x64.ActiveCfg = Debug MSVC - No Tests|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC - No Tests|x64.Build.0 = Debug MSVC - No Tests|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC - Small Strings|Win32.ActiveCfg = DebugMSVCSmallStrings|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC - Small Strings|Win32.Build.0 = DebugMSVCSmallStrings|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC - Small Strings|x64.ActiveCfg = DebugMSVCSmallStrings|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC - Small Strings|x64.Build.0 = DebugMSVCSmallStrings|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC - String Truncation Is Error|Win32.ActiveCfg = Debug|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC - String Truncation Is Error|Win32.Build.0 = Debug|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC - String Truncation Is Error|x64.ActiveCfg = DebugStringTruncationIsError|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC - String Truncation Is Error|x64.Build.0 = DebugStringTruncationIsError|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC 64|Win32.ActiveCfg = Debug|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC 64|Win32.Build.0 = Debug|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC 64|x64.ActiveCfg = Debug64|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC 64|x64.Build.0 = Debug64|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC C++20 - No STL|Win32.ActiveCfg = Debug MSVC C++20 - No STL|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC C++20 - No STL|Win32.Build.0 = Debug MSVC C++20 - No STL|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC C++20 - No STL|x64.ActiveCfg = Debug MSVC C++20 - No STL|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC C++20 - No STL|x64.Build.0 = Debug MSVC C++20 - No STL|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC C++20|Win32.ActiveCfg = Debug MSVC C++20|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC C++20|Win32.Build.0 = Debug MSVC C++20|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC C++20|x64.ActiveCfg = Debug MSVC C++20|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC C++20|x64.Build.0 = Debug MSVC C++20|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC|Win32.ActiveCfg = Debug|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC|Win32.Build.0 = Debug|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC|x64.ActiveCfg = Debug|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug MSVC|x64.Build.0 = Debug|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug|Win32.ActiveCfg = Debug|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug|Win32.Build.0 = Debug|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug|x64.ActiveCfg = Debug|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug|x64.Build.0 = Debug|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.MSVC Debug Appveyor|Win32.ActiveCfg = Debug|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.MSVC Debug Appveyor|Win32.Build.0 = Debug|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.MSVC Debug Appveyor|x64.ActiveCfg = MSVC Debug Appveyor|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.MSVC Debug Appveyor|x64.Build.0 = MSVC Debug Appveyor|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.MSVC Debug No STL Appveyor|Win32.ActiveCfg = MSVC Debug No STL Appveyor|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.MSVC Debug No STL Appveyor|Win32.Build.0 = MSVC Debug No STL Appveyor|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.MSVC Debug No STL Appveyor|x64.ActiveCfg = MSVC Debug No STL Appveyor|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.MSVC Debug No STL Appveyor|x64.Build.0 = MSVC Debug No STL Appveyor|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Release|Win32.ActiveCfg = Release|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Release|Win32.Build.0 = Release|Win32
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Release|x64.ActiveCfg = Release|x64
{C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0E35F961-E9EF-40C4-8E3E-2EC79B1D44B8}
EndGlobalSection
EndGlobal