mirror of
https://github.com/ETLCPP/etl.git
synced 2026-04-30 19:09:10 +08:00
Merge branch 'development' into fix-tuple-review
This commit is contained in:
commit
be47621909
@ -2005,11 +2005,12 @@ namespace etl
|
||||
|
||||
for (TIterator1 i = begin1; i != end1; ++i)
|
||||
{
|
||||
if (i == etl::find_if(begin1, i, etl::bind1st(predicate, *i)))
|
||||
const typename etl::binder1st<TBinaryPredicate> predicate_is_i = etl::bind1st(predicate, *i);
|
||||
if (i == etl::find_if(begin1, i, predicate_is_i))
|
||||
{
|
||||
size_t n = etl::count_if(begin2, end2, etl::bind1st(predicate, *i));
|
||||
size_t n = etl::count_if(begin2, end2, predicate_is_i);
|
||||
|
||||
if (n == 0 || size_t(etl::count_if(i, end1, etl::bind1st(predicate, *i))) != n)
|
||||
if (n == 0 || size_t(etl::count_if(i, end1, predicate_is_i)) != n)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -2038,15 +2039,18 @@ namespace etl
|
||||
return false;
|
||||
}
|
||||
|
||||
for (TIterator1 i = begin1; i != end1; ++i)
|
||||
if (begin1 != end1)
|
||||
{
|
||||
if (i == etl::find(begin1, i, *i))
|
||||
for (TIterator1 i = begin1; i != end1; ++i)
|
||||
{
|
||||
size_t n = etl::count(begin2, end2, *i);
|
||||
|
||||
if (n == 0 || size_t(etl::count(i, end1, *i)) != n)
|
||||
if (i == etl::find(begin1, i, *i))
|
||||
{
|
||||
return false;
|
||||
size_t n = etl::count(begin2, end2, *i);
|
||||
|
||||
if (n == 0 || size_t(etl::count(i, end1, *i)) != n)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2073,15 +2077,19 @@ namespace etl
|
||||
return false;
|
||||
}
|
||||
|
||||
for (TIterator1 i = begin1; i != end1; ++i)
|
||||
if (begin1 != end1)
|
||||
{
|
||||
if (i == etl::find_if(begin1, i, etl::bind1st(predicate, *i)))
|
||||
for (TIterator1 i = begin1; i != end1; ++i)
|
||||
{
|
||||
size_t n = etl::count_if(begin2, end2, etl::bind1st(predicate, *i));
|
||||
|
||||
if (n == 0 || size_t(etl::count_if(i, end1, etl::bind1st(predicate, *i))) != n)
|
||||
const typename etl::binder1st<TBinaryPredicate> predicate_is_i = etl::bind1st(predicate, *i);
|
||||
if (i == etl::find_if(begin1, i, predicate_is_i))
|
||||
{
|
||||
return false;
|
||||
size_t n = etl::count_if(begin2, end2, predicate_is_i);
|
||||
|
||||
if (n == 0 || size_t(etl::count_if(i, end1, predicate_is_i)) != n)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2089,6 +2097,132 @@ namespace etl
|
||||
return true;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// next_permutation
|
||||
///\ingroup algorithm
|
||||
///<a href="http://en.cppreference.com/w/cpp/algorithm/next_permutation"></a>
|
||||
//***************************************************************************
|
||||
template <typename TIterator, typename TCompare>
|
||||
ETL_CONSTEXPR14
|
||||
bool next_permutation(TIterator first, TIterator last, TCompare compare)
|
||||
{
|
||||
if (first == last)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
TIterator i = last;
|
||||
--i;
|
||||
|
||||
if (first == i)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
TIterator i1 = i;
|
||||
--i;
|
||||
|
||||
if (compare(*i, *i1))
|
||||
{
|
||||
TIterator j = last;
|
||||
--j;
|
||||
|
||||
while (!compare(*i, *j))
|
||||
{
|
||||
--j;
|
||||
}
|
||||
|
||||
etl::iter_swap(i, j);
|
||||
etl::reverse(i1, last);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (i == first)
|
||||
{
|
||||
etl::reverse(first, last);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// next_permutation
|
||||
///\ingroup algorithm
|
||||
///<a href="http://en.cppreference.com/w/cpp/algorithm/next_permutation"></a>
|
||||
//***************************************************************************
|
||||
template <typename TIterator>
|
||||
ETL_CONSTEXPR14
|
||||
bool next_permutation(TIterator first, TIterator last)
|
||||
{
|
||||
typedef etl::less<typename etl::iterator_traits<TIterator>::value_type> compare;
|
||||
return etl::next_permutation(first, last, compare());
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// prev_permutation
|
||||
///\ingroup algorithm
|
||||
///<a href="http://en.cppreference.com/w/cpp/algorithm/prev_permutation"></a>
|
||||
//***************************************************************************
|
||||
template <typename TIterator, typename TCompare>
|
||||
ETL_CONSTEXPR14
|
||||
bool prev_permutation(TIterator first, TIterator last, TCompare compare)
|
||||
{
|
||||
if (first == last)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
TIterator i = last;
|
||||
--i;
|
||||
|
||||
if (first == i)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
TIterator i1 = i;
|
||||
--i;
|
||||
|
||||
if (compare(*i1, *i))
|
||||
{
|
||||
TIterator j = last;
|
||||
--j;
|
||||
|
||||
while (!compare(*j, *i))
|
||||
{
|
||||
--j;
|
||||
}
|
||||
|
||||
etl::iter_swap(i, j);
|
||||
etl::reverse(i1, last);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (i == first)
|
||||
{
|
||||
etl::reverse(first, last);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// prev_permutation
|
||||
///\ingroup algorithm
|
||||
///<a href="http://en.cppreference.com/w/cpp/algorithm/prev_permutation"></a>
|
||||
//***************************************************************************
|
||||
template <typename TIterator>
|
||||
ETL_CONSTEXPR14
|
||||
bool prev_permutation(TIterator first, TIterator last)
|
||||
{
|
||||
typedef etl::less<typename etl::iterator_traits<TIterator>::value_type> compare;
|
||||
return etl::prev_permutation(first, last, compare());
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// is_partitioned
|
||||
///\ingroup algorithm
|
||||
|
||||
@ -169,21 +169,19 @@ namespace etl
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Constructor from value type.
|
||||
/// Converting constructor from value type.
|
||||
/// Constructs T in-place from U&&, without requiring T to be
|
||||
/// copy/move constructible.
|
||||
//***************************************************************************
|
||||
template <typename U,
|
||||
typename etl::enable_if<
|
||||
etl::is_constructible<T, U&&>::value &&
|
||||
!etl::is_same<typename etl::decay<U>::type, etl::in_place_t>::value &&
|
||||
!etl::is_same<typename etl::decay<U>::type, optional_impl>::value, int>::type = 0>
|
||||
ETL_CONSTEXPR20_STL
|
||||
optional_impl(const T& value_)
|
||||
optional_impl(U&& value_)
|
||||
{
|
||||
storage.construct(value_);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Constructor from value type.
|
||||
//***************************************************************************
|
||||
ETL_CONSTEXPR20_STL
|
||||
optional_impl(T&& value_)
|
||||
{
|
||||
storage.construct(etl::move(value_));
|
||||
storage.construct(etl::forward<U>(value_));
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
@ -280,23 +278,24 @@ namespace etl
|
||||
//***************************************************************************
|
||||
/// Assignment operator from value type.
|
||||
//***************************************************************************
|
||||
#if ETL_USING_CPP11
|
||||
template <typename U,
|
||||
typename etl::enable_if<
|
||||
etl::is_constructible<T, U&&>::value &&
|
||||
!etl::is_same<typename etl::decay<U>::type, optional_impl>::value, int>::type = 0>
|
||||
ETL_CONSTEXPR20_STL
|
||||
optional_impl& operator =(U&& value_)
|
||||
{
|
||||
storage.construct(etl::forward<U>(value_));
|
||||
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
ETL_CONSTEXPR20_STL
|
||||
optional_impl& operator =(const T& value_)
|
||||
{
|
||||
storage.construct(value_);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
/// Assignment operator from value type.
|
||||
//***************************************************************************
|
||||
ETL_CONSTEXPR20_STL
|
||||
optional_impl& operator =(T&& value_)
|
||||
{
|
||||
storage.construct(etl::move(value_));
|
||||
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
@ -1442,22 +1441,36 @@ namespace etl
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
/// Construct from value type.
|
||||
/// Converting constructor from value type.
|
||||
/// Constructs T in-place from U&&, without requiring T to be
|
||||
/// copy/move constructible.
|
||||
//***************************************************************************
|
||||
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
|
||||
template <typename U,
|
||||
typename etl::enable_if<
|
||||
etl::is_constructible<T, U&&>::value &&
|
||||
!etl::is_same<typename etl::decay<U>::type, etl::optional<T>>::value &&
|
||||
!etl::is_same<typename etl::decay<U>::type, etl::in_place_t>::value &&
|
||||
!etl::is_same<typename etl::decay<U>::type, etl::nullopt_t>::value &&
|
||||
etl::is_pod<typename etl::remove_cv<T>::type>::value, int>::type = 0>
|
||||
ETL_CONSTEXPR14
|
||||
optional(const T& value_)
|
||||
: impl_t(value_)
|
||||
optional(U&& value_)
|
||||
: impl_t(etl::forward<U>(value_))
|
||||
{
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Construct from value type.
|
||||
/// Converting constructor from value type.
|
||||
//***************************************************************************
|
||||
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
|
||||
template <typename U,
|
||||
typename etl::enable_if<
|
||||
etl::is_constructible<T, U&&>::value &&
|
||||
!etl::is_same<typename etl::decay<U>::type, etl::optional<T>>::value &&
|
||||
!etl::is_same<typename etl::decay<U>::type, etl::in_place_t>::value &&
|
||||
!etl::is_same<typename etl::decay<U>::type, etl::nullopt_t>::value &&
|
||||
!etl::is_pod<typename etl::remove_cv<T>::type>::value, int>::type = 0>
|
||||
ETL_CONSTEXPR20_STL
|
||||
optional(const T& value_)
|
||||
: impl_t(value_)
|
||||
optional(U&& value_)
|
||||
: impl_t(etl::forward<U>(value_))
|
||||
{
|
||||
}
|
||||
#else
|
||||
@ -1470,29 +1483,6 @@ namespace etl
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
/// Move construct from value type.
|
||||
//***************************************************************************
|
||||
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
|
||||
ETL_CONSTEXPR14
|
||||
optional(T&& value_)
|
||||
: impl_t(etl::move(value_))
|
||||
{
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Move construct from value type.
|
||||
//***************************************************************************
|
||||
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
|
||||
ETL_CONSTEXPR20_STL
|
||||
optional(T&& value_)
|
||||
: impl_t(etl::move(value_))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
/// Emplace construct from arguments.
|
||||
@ -1641,25 +1631,35 @@ namespace etl
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
/// Assignment operator from value type.
|
||||
/// Converting assignment operator from value type.
|
||||
//***************************************************************************
|
||||
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
|
||||
template <typename U,
|
||||
typename etl::enable_if<
|
||||
etl::is_constructible<T, U&&>::value &&
|
||||
!etl::is_same<typename etl::decay<U>::type, etl::optional<T>>::value &&
|
||||
!etl::is_same<typename etl::decay<U>::type, etl::nullopt_t>::value &&
|
||||
etl::is_pod<typename etl::remove_cv<T>::type>::value, int>::type = 0>
|
||||
ETL_CONSTEXPR14
|
||||
optional& operator =(const T& value_)
|
||||
optional& operator =(U&& value_)
|
||||
{
|
||||
impl_t::operator=(value_);
|
||||
impl_t::operator=(etl::forward<U>(value_));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Assignment operator from value type.
|
||||
/// Converting assignment operator from value type.
|
||||
//***************************************************************************
|
||||
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
|
||||
template <typename U,
|
||||
typename etl::enable_if<
|
||||
etl::is_constructible<T, U&&>::value &&
|
||||
!etl::is_same<typename etl::decay<U>::type, etl::optional<T>>::value &&
|
||||
!etl::is_same<typename etl::decay<U>::type, etl::nullopt_t>::value &&
|
||||
!etl::is_pod<typename etl::remove_cv<T>::type>::value, int>::type = 0>
|
||||
ETL_CONSTEXPR20_STL
|
||||
optional& operator =(const T& value_)
|
||||
optional& operator =(U&& value_)
|
||||
{
|
||||
impl_t::operator=(value_);
|
||||
impl_t::operator=(etl::forward<U>(value_));
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -1675,32 +1675,6 @@ namespace etl
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
/// Move assignment operator from value type.
|
||||
//***************************************************************************
|
||||
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
|
||||
ETL_CONSTEXPR14
|
||||
optional& operator =(T&& value_)
|
||||
{
|
||||
impl_t::operator=(etl::move(value_));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Move assignment operator from value type.
|
||||
//***************************************************************************
|
||||
template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
|
||||
ETL_CONSTEXPR20_STL
|
||||
optional& operator =(T&& value_)
|
||||
{
|
||||
impl_t::operator=(etl::move(value_));
|
||||
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// Returns an iterator to the beginning of the optional.
|
||||
//***************************************************************************
|
||||
|
||||
@ -33,7 +33,11 @@ SOFTWARE.
|
||||
#endif
|
||||
|
||||
#if !defined(ETL_CHRONO_SYSTEM_CLOCK_DURATION)
|
||||
#define ETL_CHRONO_SYSTEM_CLOCK_DURATION etl::chrono::nanoseconds
|
||||
#if (INT_MAX >= INT32_MAX)
|
||||
#define ETL_CHRONO_SYSTEM_CLOCK_DURATION etl::chrono::nanoseconds
|
||||
#else
|
||||
#define ETL_CHRONO_SYSTEM_CLOCK_DURATION etl::chrono::milliseconds
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(ETL_CHRONO_SYSTEM_CLOCK_IS_STEADY)
|
||||
@ -41,7 +45,11 @@ SOFTWARE.
|
||||
#endif
|
||||
|
||||
#if !defined(ETL_CHRONO_HIGH_RESOLUTION_CLOCK_DURATION)
|
||||
#define ETL_CHRONO_HIGH_RESOLUTION_CLOCK_DURATION etl::chrono::nanoseconds
|
||||
#if (INT_MAX >= INT32_MAX)
|
||||
#define ETL_CHRONO_HIGH_RESOLUTION_CLOCK_DURATION etl::chrono::nanoseconds
|
||||
#else
|
||||
#define ETL_CHRONO_HIGH_RESOLUTION_CLOCK_DURATION etl::chrono::milliseconds
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(ETL_CHRONO_HIGH_RESOLUTION_CLOCK_IS_STEADY)
|
||||
@ -49,7 +57,11 @@ SOFTWARE.
|
||||
#endif
|
||||
|
||||
#if !defined(ETL_CHRONO_STEADY_CLOCK_DURATION)
|
||||
#define ETL_CHRONO_STEADY_CLOCK_DURATION etl::chrono::nanoseconds
|
||||
#if (INT_MAX >= INT32_MAX)
|
||||
#define ETL_CHRONO_STEADY_CLOCK_DURATION etl::chrono::nanoseconds
|
||||
#else
|
||||
#define ETL_CHRONO_STEADY_CLOCK_DURATION etl::chrono::milliseconds
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern "C" ETL_CHRONO_SYSTEM_CLOCK_DURATION::rep etl_get_system_clock();
|
||||
|
||||
@ -315,13 +315,17 @@ namespace etl
|
||||
/// Duration types
|
||||
//***********************************************************************
|
||||
#if (ETL_USING_64BIT_TYPES)
|
||||
#if (INT_MAX >= INT32_MAX)
|
||||
using nanoseconds = etl::chrono::duration<int64_t, etl::nano>;
|
||||
using microseconds = etl::chrono::duration<int64_t, etl::micro>;
|
||||
#endif
|
||||
using milliseconds = etl::chrono::duration<int64_t, etl::milli>;
|
||||
using seconds = etl::chrono::duration<int64_t, etl::ratio<1U>>;
|
||||
#else
|
||||
#if (INT_MAX >= INT32_MAX)
|
||||
using nanoseconds = etl::chrono::duration<int32_t, etl::nano>;
|
||||
using microseconds = etl::chrono::duration<int32_t, etl::micro>;
|
||||
#endif
|
||||
using milliseconds = etl::chrono::duration<int32_t, etl::milli>;
|
||||
using seconds = etl::chrono::duration<int32_t, etl::ratio<1U>>;
|
||||
#endif
|
||||
@ -811,6 +815,7 @@ namespace etl
|
||||
return etl::chrono::duration<double, milli>(s);
|
||||
}
|
||||
|
||||
#if (INT_MAX >= INT32_MAX)
|
||||
//***********************************************************************
|
||||
/// Literal for microseconds duration
|
||||
//***********************************************************************
|
||||
@ -848,7 +853,7 @@ namespace etl
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
/// Literal for floating point microseconds duration
|
||||
/// Literal for floating point nanoseconds duration
|
||||
//***********************************************************************
|
||||
#if ETL_USING_VERBOSE_CHRONO_LITERALS
|
||||
inline ETL_CONSTEXPR14 etl::chrono::duration<double, nano> operator ""_nanoseconds(long double s) ETL_NOEXCEPT
|
||||
@ -858,6 +863,7 @@ namespace etl
|
||||
{
|
||||
return etl::chrono::duration<double, nano>(s);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1068,7 +1068,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
|
||||
{
|
||||
return (pend - pbegin);
|
||||
return static_cast<size_t>(pend - pbegin);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -1076,7 +1076,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
|
||||
{
|
||||
return sizeof(element_type) * (pend - pbegin);
|
||||
return sizeof(element_type) * static_cast<size_t>(pend - pbegin);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -1262,7 +1262,7 @@ namespace etl
|
||||
ETL_ASSERT(etl::is_aligned<etl::alignment_of<TNew>::value>(pbegin), ETL_ERROR(span_alignment_exception));
|
||||
|
||||
return etl::span<TNew, etl::dynamic_extent>(reinterpret_cast<TNew*>(pbegin),
|
||||
(pend - pbegin) * sizeof(element_type) / sizeof(TNew));
|
||||
static_cast<size_t>(pend - pbegin) * sizeof(element_type) / sizeof(TNew));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
|
||||
@ -345,8 +345,8 @@ namespace etl
|
||||
{
|
||||
memcpy(store, &value, Size_);
|
||||
|
||||
#if ETL_HAS_CONSTEXPR_ENDIANESS
|
||||
if ETL_IF_CONSTEXPR(Endian_ == etl::endianness::value())
|
||||
#if ETL_HAS_CONSTEXPR_ENDIANNESS
|
||||
if ETL_IF_CONSTEXPR(Endian_ != etl::endianness::value())
|
||||
#else
|
||||
if (Endian_ != etl::endianness::value())
|
||||
#endif
|
||||
@ -361,8 +361,8 @@ namespace etl
|
||||
{
|
||||
memcpy(&value, store, Size_);
|
||||
|
||||
#if ETL_HAS_CONSTEXPR_ENDIANESS
|
||||
if ETL_IF_CONSTEXPR(Endian == etl::endianness::value())
|
||||
#if ETL_HAS_CONSTEXPR_ENDIANNESS
|
||||
if ETL_IF_CONSTEXPR(Endian_ != etl::endianness::value())
|
||||
#else
|
||||
if (Endian_ != etl::endianness::value())
|
||||
#endif
|
||||
@ -402,8 +402,8 @@ namespace etl
|
||||
{
|
||||
memcpy(store, &value, Size_);
|
||||
|
||||
#if ETL_HAS_CONSTEXPR_ENDIANESS
|
||||
if ETL_IF_CONSTEXPR(Endian_ == etl::endianness::value())
|
||||
#if ETL_HAS_CONSTEXPR_ENDIANNESS
|
||||
if ETL_IF_CONSTEXPR(Endian_ != etl::endianness::value())
|
||||
#else
|
||||
if (Endian_ != etl::endianness::value())
|
||||
#endif
|
||||
@ -418,14 +418,14 @@ namespace etl
|
||||
{
|
||||
memcpy(&value, store, Size_);
|
||||
|
||||
#if ETL_HAS_CONSTEXPR_ENDIANESS
|
||||
if ETL_IF_CONSTEXPR(Endian == etl::endianness::value())
|
||||
#if ETL_HAS_CONSTEXPR_ENDIANNESS
|
||||
if ETL_IF_CONSTEXPR(Endian_ != etl::endianness::value())
|
||||
#else
|
||||
if (Endian_ != etl::endianness::value())
|
||||
if (Endian_ != etl::endianness::value())
|
||||
#endif
|
||||
{
|
||||
etl::reverse(reinterpret_cast<pointer>(&value), reinterpret_cast<pointer>(&value) + Size_);
|
||||
}
|
||||
{
|
||||
etl::reverse(reinterpret_cast<pointer>(&value), reinterpret_cast<pointer>(&value) + Size_);
|
||||
}
|
||||
}
|
||||
|
||||
//*******************************
|
||||
|
||||
@ -116,6 +116,14 @@ namespace
|
||||
}
|
||||
};
|
||||
|
||||
struct DataEquivalenceByA : public etl::binary_function<Data, Data, bool>
|
||||
{
|
||||
bool operator ()(const Data& lhs, const Data& rhs) const
|
||||
{
|
||||
return lhs.a == rhs.a;
|
||||
}
|
||||
};
|
||||
|
||||
Data dataD[10] = { Data(1, 2), Data(2, 1), Data(3, 4), Data(4, 3), Data(5, 6), Data(6, 5), Data(7, 8), Data(8, 7), Data(9, 10), Data(10, 9) };
|
||||
|
||||
struct Greater : public etl::binary_function<int, int, bool>
|
||||
@ -3449,18 +3457,174 @@ namespace
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(stable_sort_greater)
|
||||
TEST(next_permutation)
|
||||
{
|
||||
std::vector<NDC> initial_data = { NDC(1, 1), NDC(2, 1), NDC(3, 1), NDC(2, 2), NDC(3, 2), NDC(4, 1), NDC(2, 3), NDC(3, 3), NDC(5, 1) };
|
||||
std::array<int, 4U> expected = { 1, 1, 2, 2 };
|
||||
std::array<int, 4U> result = expected;
|
||||
|
||||
std::vector<NDC> data1(initial_data);
|
||||
std::vector<NDC> data2(initial_data);
|
||||
for (size_t i = 0U; i < 8U; ++i)
|
||||
{
|
||||
bool expected_has_next = std::next_permutation(expected.begin(), expected.end());
|
||||
bool result_has_next = etl::next_permutation(result.begin(), result.end());
|
||||
|
||||
std::stable_sort(data1.begin(), data1.end(), std::greater<NDC>());
|
||||
etl::stable_sort(data2.begin(), data2.end(), std::greater<NDC>());
|
||||
CHECK_EQUAL(expected_has_next, result_has_next);
|
||||
CHECK_ARRAY_EQUAL(expected.data(), result.data(), result.size());
|
||||
}
|
||||
|
||||
bool is_same = std::equal(data1.begin(), data1.end(), data2.begin(), NDC::are_identical);
|
||||
CHECK(is_same);
|
||||
// Check one past the end.
|
||||
bool expected_has_next = std::next_permutation(expected.begin(), expected.end());
|
||||
bool result_has_next = etl::next_permutation(result.begin(), result.end());
|
||||
CHECK_EQUAL(expected_has_next, result_has_next);
|
||||
CHECK_ARRAY_EQUAL(expected.data(), result.data(), result.size());
|
||||
|
||||
int single_expected[] = { 1 };
|
||||
int single_result[] = { 1 };
|
||||
|
||||
expected_has_next = std::next_permutation(std::begin(single_expected), std::end(single_expected));
|
||||
result_has_next = etl::next_permutation(std::begin(single_result), std::end(single_result));
|
||||
|
||||
CHECK_EQUAL(expected_has_next, result_has_next);
|
||||
CHECK_ARRAY_EQUAL(single_expected, single_result, 1U);
|
||||
|
||||
// Check for what happens if the beginning and end are the same.
|
||||
expected_has_next = std::next_permutation(std::begin(single_expected), std::begin(single_expected));
|
||||
result_has_next = etl::next_permutation(std::begin(single_result), std::begin(single_result));
|
||||
|
||||
CHECK_EQUAL(expected_has_next, result_has_next);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(next_permutation_compare)
|
||||
{
|
||||
std::array<int, 4U> expected = { 3, 2, 2, 1 };
|
||||
std::array<int, 4U> result = expected;
|
||||
|
||||
for (size_t i = 0U; i < 8U; ++i)
|
||||
{
|
||||
bool expected_has_next = std::next_permutation(expected.begin(), expected.end(), std::greater<int>());
|
||||
bool result_has_next = etl::next_permutation(result.begin(), result.end(), std::greater<int>());
|
||||
|
||||
CHECK_EQUAL(expected_has_next, result_has_next);
|
||||
CHECK_ARRAY_EQUAL(expected.data(), result.data(), result.size());
|
||||
}
|
||||
|
||||
// Check one past the end.
|
||||
bool expected_has_next = std::next_permutation(expected.begin(), expected.end(), std::greater<int>());
|
||||
bool result_has_next = etl::next_permutation(result.begin(), result.end(), std::greater<int>());
|
||||
CHECK_EQUAL(expected_has_next, result_has_next);
|
||||
CHECK_ARRAY_EQUAL(expected.data(), result.data(), result.size());
|
||||
|
||||
int single_expected[] = { 1 };
|
||||
int single_result[] = { 1 };
|
||||
|
||||
// Check for what happens if the beginning and end are the same.
|
||||
expected_has_next = std::next_permutation(std::begin(single_expected), std::begin(single_expected), std::greater<int>());
|
||||
result_has_next = etl::next_permutation(std::begin(single_result), std::begin(single_result), std::greater<int>());
|
||||
|
||||
CHECK_EQUAL(expected_has_next, result_has_next);
|
||||
CHECK_ARRAY_EQUAL(single_expected, single_result, 1U);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(prev_permutation)
|
||||
{
|
||||
std::array<int, 4U> expected = { 2, 2, 1, 1 };
|
||||
std::array<int, 4U> result = expected;
|
||||
|
||||
for (size_t i = 0U; i < 8U; ++i)
|
||||
{
|
||||
bool expected_has_prev = std::prev_permutation(expected.begin(), expected.end());
|
||||
bool result_has_prev = etl::prev_permutation(result.begin(), result.end());
|
||||
|
||||
CHECK_EQUAL(expected_has_prev, result_has_prev);
|
||||
CHECK_ARRAY_EQUAL(expected.data(), result.data(), result.size());
|
||||
}
|
||||
|
||||
// Check one past the end.
|
||||
bool expected_has_prev = std::prev_permutation(expected.begin(), expected.end());
|
||||
bool result_has_prev = etl::prev_permutation(result.begin(), result.end());
|
||||
CHECK_EQUAL(expected_has_prev, result_has_prev);
|
||||
CHECK_ARRAY_EQUAL(expected.data(), result.data(), result.size());
|
||||
|
||||
int single_expected[] = { 1 };
|
||||
int single_result[] = { 1 };
|
||||
|
||||
expected_has_prev = std::prev_permutation(std::begin(single_expected), std::end(single_expected));
|
||||
result_has_prev = etl::prev_permutation(std::begin(single_result), std::end(single_result));
|
||||
|
||||
CHECK_EQUAL(expected_has_prev, result_has_prev);
|
||||
CHECK_ARRAY_EQUAL(single_expected, single_result, 1U);
|
||||
|
||||
// Check for what happens if the beginning and end are the same.
|
||||
expected_has_prev = std::prev_permutation(std::begin(single_expected), std::begin(single_expected));
|
||||
result_has_prev = etl::prev_permutation(std::begin(single_result), std::begin(single_result));
|
||||
|
||||
CHECK_EQUAL(expected_has_prev, result_has_prev);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(prev_permutation_compare)
|
||||
{
|
||||
std::array<int, 4U> expected = { 1, 1, 2, 3 };
|
||||
std::array<int, 4U> result = expected;
|
||||
|
||||
for (size_t i = 0U; i < 8U; ++i)
|
||||
{
|
||||
bool expected_has_prev = std::prev_permutation(expected.begin(), expected.end(), std::greater<int>());
|
||||
bool result_has_prev = etl::prev_permutation(result.begin(), result.end(), std::greater<int>());
|
||||
|
||||
CHECK_EQUAL(expected_has_prev, result_has_prev);
|
||||
CHECK_ARRAY_EQUAL(expected.data(), result.data(), result.size());
|
||||
}
|
||||
|
||||
// Check one past the end.
|
||||
bool expected_has_prev = std::prev_permutation(expected.begin(), expected.end(), std::greater<int>());
|
||||
bool result_has_prev = etl::prev_permutation(result.begin(), result.end(), std::greater<int>());
|
||||
CHECK_EQUAL(expected_has_prev, result_has_prev);
|
||||
CHECK_ARRAY_EQUAL(expected.data(), result.data(), result.size());
|
||||
|
||||
int single_expected[] = { 1 };
|
||||
int single_result[] = { 1 };
|
||||
|
||||
// Check for what happens if the beginning and end are the same.
|
||||
expected_has_prev = std::prev_permutation(std::begin(single_expected), std::begin(single_expected), std::greater<int>());
|
||||
result_has_prev = etl::prev_permutation(std::begin(single_result), std::begin(single_result), std::greater<int>());
|
||||
|
||||
CHECK_EQUAL(expected_has_prev, result_has_prev);
|
||||
CHECK_ARRAY_EQUAL(single_expected, single_result, 1U);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(is_permutation_length_mismatch)
|
||||
{
|
||||
int data1[] = { 1, 2, 3 };
|
||||
int data2[] = { 1, 2, 3, 4 };
|
||||
|
||||
bool is_permutation = etl::is_permutation(std::begin(data1), std::end(data1), std::begin(data2), std::end(data2));
|
||||
CHECK_FALSE(is_permutation);
|
||||
|
||||
is_permutation = etl::is_permutation(std::begin(data1), std::end(data1), std::begin(data2), std::end(data2), etl::equal_to<int>());
|
||||
CHECK_FALSE(is_permutation);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(is_permutation_predicate)
|
||||
{
|
||||
Data data1[] = { Data(1, 10), Data(2, 20), Data(2, 30), Data(3, 40) };
|
||||
Data permutation[] = { Data(2, 200), Data(1, 100), Data(3, 300), Data(2, 400) };
|
||||
Data not_permutation[] = { Data(2, 200), Data(1, 100), Data(4, 300), Data(2, 400) };
|
||||
|
||||
bool is_permutation = etl::is_permutation(std::begin(data1), std::end(data1), std::begin(permutation), DataEquivalenceByA());
|
||||
CHECK_TRUE(is_permutation);
|
||||
|
||||
is_permutation = etl::is_permutation(std::begin(data1), std::end(data1), std::begin(not_permutation), DataEquivalenceByA());
|
||||
CHECK_FALSE(is_permutation);
|
||||
|
||||
is_permutation = etl::is_permutation(std::begin(data1), std::end(data1), std::begin(permutation), std::end(permutation), DataEquivalenceByA());
|
||||
CHECK_TRUE(is_permutation);
|
||||
|
||||
is_permutation = etl::is_permutation(std::begin(data1), std::end(data1), std::begin(not_permutation), std::end(not_permutation), DataEquivalenceByA());
|
||||
CHECK_FALSE(is_permutation);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
|
||||
@ -35,6 +35,8 @@ SOFTWARE.
|
||||
|
||||
#include "etl/crc8_nrsc5.h"
|
||||
|
||||
#include <etl/endianness.h>
|
||||
|
||||
//*****************************************************************************
|
||||
// The results for these tests were created from https://crccalc.com/
|
||||
//*****************************************************************************
|
||||
@ -115,7 +117,15 @@ namespace
|
||||
TEST(test_crc8_nrsc5_4_add_range_endian)
|
||||
{
|
||||
std::vector<uint8_t> data1 = { 0x01U, 0x02U, 0x03U, 0x04U, 0x05U, 0x06U, 0x07U, 0x08U };
|
||||
std::vector<uint32_t> data2 = { 0x04030201UL, 0x08070605UL };
|
||||
std::vector<uint32_t> data2;
|
||||
if (etl::endianness::value() == etl::endian::little)
|
||||
{
|
||||
data2 = { 0x04030201UL, 0x08070605UL };
|
||||
}
|
||||
else
|
||||
{
|
||||
data2 = { 0x01020304UL, 0x05060708UL };
|
||||
}
|
||||
std::vector<uint8_t> data3 = { 0x08U, 0x07U, 0x06U, 0x05U, 0x04U, 0x03U, 0x02U, 0x01U };
|
||||
|
||||
uint8_t crc1 = etl::crc8_nrsc5_t4(data1.begin(), data1.end());
|
||||
@ -198,7 +208,15 @@ namespace
|
||||
TEST(test_crc8_nrsc5_16_add_range_endian)
|
||||
{
|
||||
std::vector<uint8_t> data1 = { 0x01U, 0x02U, 0x03U, 0x04U, 0x05U, 0x06U, 0x07U, 0x08U };
|
||||
std::vector<uint32_t> data2 = { 0x04030201UL, 0x08070605UL };
|
||||
std::vector<uint32_t> data2;
|
||||
if (etl::endianness::value() == etl::endian::little)
|
||||
{
|
||||
data2 = { 0x04030201UL, 0x08070605UL };
|
||||
}
|
||||
else
|
||||
{
|
||||
data2 = { 0x01020304UL, 0x05060708UL };
|
||||
}
|
||||
std::vector<uint8_t> data3 = { 0x08U, 0x07U, 0x06U, 0x05U, 0x04U, 0x03U, 0x02U, 0x01U };
|
||||
|
||||
uint8_t crc1 = etl::crc8_nrsc5_t16(data1.begin(), data1.end());
|
||||
@ -281,7 +299,15 @@ namespace
|
||||
TEST(test_crc8_nrsc5_256_add_range_endian)
|
||||
{
|
||||
std::vector<uint8_t> data1 = { 0x01U, 0x02U, 0x03U, 0x04U, 0x05U, 0x06U, 0x07U, 0x08U };
|
||||
std::vector<uint32_t> data2 = { 0x04030201UL, 0x08070605UL };
|
||||
std::vector<uint32_t> data2;
|
||||
if (etl::endianness::value() == etl::endian::little)
|
||||
{
|
||||
data2 = { 0x04030201UL, 0x08070605UL };
|
||||
}
|
||||
else
|
||||
{
|
||||
data2 = { 0x01020304UL, 0x05060708UL };
|
||||
}
|
||||
std::vector<uint8_t> data3 = { 0x08U, 0x07U, 0x06U, 0x05U, 0x04U, 0x03U, 0x02U, 0x01U };
|
||||
|
||||
uint8_t crc1 = etl::crc8_nrsc5(data1.begin(), data1.end());
|
||||
|
||||
@ -1118,5 +1118,46 @@ namespace
|
||||
|
||||
CHECK_EQUAL(42, *opt);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
// GitHub issue #146: etl::optional doesn't compile with deleted copy constructor
|
||||
//*************************************************************************
|
||||
#if ETL_USING_CPP11
|
||||
struct Issue146_NonCopyable
|
||||
{
|
||||
Issue146_NonCopyable(int some) : _some(some) {}
|
||||
Issue146_NonCopyable(const Issue146_NonCopyable&) = delete;
|
||||
Issue146_NonCopyable(Issue146_NonCopyable&&) = delete;
|
||||
Issue146_NonCopyable& operator=(const Issue146_NonCopyable&) = delete;
|
||||
|
||||
int _some;
|
||||
};
|
||||
|
||||
struct Issue146_Container
|
||||
{
|
||||
Issue146_Container(int a_val) : a(a_val) {}
|
||||
Issue146_Container() : a(etl::nullopt) {}
|
||||
|
||||
etl::optional<Issue146_NonCopyable> a;
|
||||
};
|
||||
|
||||
TEST(test_optional_issue_146_deleted_copy_ctor)
|
||||
{
|
||||
// etl::optional<T> should compile when T has deleted copy/move constructors,
|
||||
// as long as T is constructible from the given arguments.
|
||||
Issue146_Container with_value(42);
|
||||
Issue146_Container without_value;
|
||||
|
||||
CHECK_TRUE(with_value.a.has_value());
|
||||
CHECK_EQUAL(42, with_value.a->_some);
|
||||
|
||||
CHECK_FALSE(without_value.a.has_value());
|
||||
|
||||
// in_place construction should also work
|
||||
etl::optional<Issue146_NonCopyable> opt(etl::in_place_t{}, 99);
|
||||
CHECK_TRUE(opt.has_value());
|
||||
CHECK_EQUAL(99, opt->_some);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -1030,6 +1030,98 @@ namespace
|
||||
CHECK_EQUAL(0x12, bev0);
|
||||
CHECK_EQUAL(0x34, bev1);
|
||||
}
|
||||
|
||||
#if ETL_HAS_CONSTEXPR_ENDIANNESS
|
||||
//*************************************************************************
|
||||
TEST(test_constexpr_endianness_integral_round_trip)
|
||||
{
|
||||
// Store a known value in LE, BE, and host-order unaligned types.
|
||||
const uint32_t value = 0x12345678U;
|
||||
|
||||
etl::le_uint32_t le_v(value);
|
||||
etl::be_uint32_t be_v(value);
|
||||
etl::host_uint32_t host_v(value);
|
||||
|
||||
// All must read back the original value.
|
||||
CHECK_EQUAL(value, uint32_t(le_v));
|
||||
CHECK_EQUAL(value, uint32_t(be_v));
|
||||
CHECK_EQUAL(value, uint32_t(host_v));
|
||||
|
||||
// Verify the storage byte order is correct.
|
||||
// LE stores LSB first: 0x78, 0x56, 0x34, 0x12
|
||||
CHECK_EQUAL(0x78, int(le_v[0]));
|
||||
CHECK_EQUAL(0x56, int(le_v[1]));
|
||||
CHECK_EQUAL(0x34, int(le_v[2]));
|
||||
CHECK_EQUAL(0x12, int(le_v[3]));
|
||||
|
||||
// BE stores MSB first: 0x12, 0x34, 0x56, 0x78
|
||||
CHECK_EQUAL(0x12, int(be_v[0]));
|
||||
CHECK_EQUAL(0x34, int(be_v[1]));
|
||||
CHECK_EQUAL(0x56, int(be_v[2]));
|
||||
CHECK_EQUAL(0x78, int(be_v[3]));
|
||||
|
||||
// Host-order must match one of the above depending on the platform.
|
||||
if (etl::endianness::value() == etl::endian::little)
|
||||
{
|
||||
CHECK_EQUAL(0x78, int(host_v[0]));
|
||||
CHECK_EQUAL(0x56, int(host_v[1]));
|
||||
CHECK_EQUAL(0x34, int(host_v[2]));
|
||||
CHECK_EQUAL(0x12, int(host_v[3]));
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK_EQUAL(0x12, int(host_v[0]));
|
||||
CHECK_EQUAL(0x34, int(host_v[1]));
|
||||
CHECK_EQUAL(0x56, int(host_v[2]));
|
||||
CHECK_EQUAL(0x78, int(host_v[3]));
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_constexpr_endianness_float_round_trip)
|
||||
{
|
||||
// Store a known float value in LE, BE, and host-order unaligned types.
|
||||
const float value = 3.1415927f;
|
||||
|
||||
etl::le_float_t le_v(value);
|
||||
etl::be_float_t be_v(value);
|
||||
etl::host_float_t host_v(value);
|
||||
|
||||
// All must read back the original value.
|
||||
CHECK_CLOSE(value, float(le_v), 0.0001f);
|
||||
CHECK_CLOSE(value, float(be_v), 0.0001f);
|
||||
CHECK_CLOSE(value, float(host_v), 0.0001f);
|
||||
|
||||
// LE and BE storage bytes must be the reverse of each other.
|
||||
CHECK_EQUAL(int(le_v[0]), int(be_v[3]));
|
||||
CHECK_EQUAL(int(le_v[1]), int(be_v[2]));
|
||||
CHECK_EQUAL(int(le_v[2]), int(be_v[1]));
|
||||
CHECK_EQUAL(int(le_v[3]), int(be_v[0]));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_constexpr_endianness_cross_endian_copy)
|
||||
{
|
||||
// Verify that converting between LE <-> BE via host works correctly.
|
||||
const uint16_t value = 0xABCDU;
|
||||
|
||||
etl::le_uint16_t le_v(value);
|
||||
etl::be_uint16_t be_v(value);
|
||||
etl::host_uint16_t host_from_le(le_v);
|
||||
etl::host_uint16_t host_from_be(be_v);
|
||||
|
||||
CHECK_EQUAL(value, uint16_t(host_from_le));
|
||||
CHECK_EQUAL(value, uint16_t(host_from_be));
|
||||
|
||||
// Round-trip: host -> le -> read back
|
||||
etl::le_uint16_t le_from_host(host_from_le);
|
||||
CHECK_EQUAL(value, uint16_t(le_from_host));
|
||||
|
||||
// Round-trip: host -> be -> read back
|
||||
etl::be_uint16_t be_from_host(host_from_be);
|
||||
CHECK_EQUAL(value, uint16_t(be_from_host));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user