span is constructible from temporary (#1338)

* Added missing files from VS2022 project

* Added global data() overloads to complement etl::size()

* Added C++03 compatible implementation of etl::is_convertible

* Updated etl::span to more closely align with std::span

* Fix etl::rotate (#1327)

Per the C++ standard, std::rotate returns first + (last - middle):

* When first == middle, return last
* When middle == last, return first

* Fix greater_equal and less_equal (#1331)

* Align comparison operators (#1330)

In functional.h, the comparison operators for equal_to and not_equal_to
mismatch between the actual comparison execution and the type inference
for the return type. This change adjusts it by using the same operator==()
in the return type inference as used in the comparison execution.

Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>

* Add missing tests (#1321)

* Add missing tests

* Typo fixes

---------

Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>

* Add ETL_FORMAT_NO_FLOATING_POINT control macro for etl::format (#1329)

When ETL_FORMAT_NO_FLOATING_POINT is defined, all floating-point formatting support (float, double, long double) is excluded from etl::format. This reduces code size on targets that do not require floating-point formatting.

Guarded sections:

- #include <cmath>

- float/double/long double in supported_format_types variant

- float/double/long double constructors in basic_format_arg

- format_floating_* functions and format_aligned_floating

- formatter<float>, formatter<double>, formatter<long double>

- Floating-point test cases in test_format.cpp

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
# Conflicts:
#	include/etl/platform.h

* Manchester documentation (#1325)

* manchester
* Added manchester code and test

* manchester
* Formatting and added missing file

* manchester
* Some functions can only be constexpr since C++14

* manchester
* Manchester decode and some refactoring

* manchester
* Added some missing typenames

* manchester
* constexpr void function not allowed in C++11

* manchester
* condition on static_assert tests

* manchester
* revert CMakeLists.txt
* Using ETL_STATIC_ASSERT
* Some cleanup

* manchester
* Added static_assert message

* manchester
* Added compile time tests

* manchester
* Added invert manchester
* Some refactoring

* manchester
* Disable test for now
* Move ETL_NODISCARD before static

* manchester
* Test for valid_span

* manchester
* Remove redundant (?) storage specifiers for template specializations. Storage specifier already given in base template

* manchester
* refactoring to get rid of specialized template functions in template class

* manchester
* cleanup

* manchester
* Added documentation comments
* Some refactoring

* manchester
* introducing namespace detail_manchester

* manchester
* Some refactoring
* Update tests

* manchester
* Some refactoring
* Removed possible undefined behavior by refactoring encode_span
* constexpr version of encode_span
* Static assertion for rare case where code doesn't work because CHAR_BIT is not the same as the number of bits in uint_least8_t

* manchester
* renamed valid to is_valid

* manchester
* renamed is_valid_span to is_valid
* Using etl exceptions in ETL_ASSERT

* manchester
* Removed _fast functions
* merged encode_in_place with encode and decode_in_place with decode
* removed _span to create normal overloads of encode and decode for span
* Some renaming and minor refactoring

* manchester
* Fix build issues

* manchester
* Conditionally compile manchester_decoded

* Update test_manchester.cpp

Removed redundant semicolon

* #1258 Manchester coding
* Formatting
* consistency: hex literals with lower case 0x

* #1258 Manchester coding
* Moved copyright to top of file
* Make constexpr encode/decode span functions equal for little and big endian platforms

* #1258 Manchester coding
* Added missing include
* Added missing 8bit/64bit guards
* Fixed is_valid for big endian platforms

* #1258 Manchester coding
* private memcpy alias

* #1258 Manchester coding
* Review comments

* #1258 Manchester coding
* Cleanup
* Fix build error

* #1258 Manchester coding
* Add manchester documentation

* #1258 Manchester coding
* Preparation for GitHub pages

* #1324 Manchester documentation
* Some small fixes

---------

Co-authored-by: Timon Zijnge <timon.zijnge@imec.nl>

* Moved and split has_size_and_data in span.h to has_size & has_data in type_traits.h

* Removed has_size_and_data traits, and move to type_traits.h

Added ETL_ASSERT for for fixed extent constructors from iterator range and begin/size

* Added macro ETL_NOEXCEPT_IF that takes a compile time boolean expression

* Changed two fixed span constructors to ETL_CONSTEXPR14 due to ETL_ASSERT in the constructor bodies

Added ETL_NOEXCEPT_IF for simpler boolean conditions
Added tests for construction from mismatched sizes

* Added definition for ETL_NOEXCEPT_IF in no C++11 path

* Changes  to disable construction from rvalue temporaries

---------

Co-authored-by: John Wellbelove <john.wellbelove@etlcpp.com>
Co-authored-by: Roland Reichwein <Roland.Reichwein@bmw.de>
Co-authored-by: Niu Zhihong <zhihong@nzhnb.com>
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Co-authored-by: Timon Zijnge <47081647+tzijnge@users.noreply.github.com>
Co-authored-by: Timon Zijnge <timon.zijnge@imec.nl>
This commit is contained in:
John Wellbelove 2026-03-12 17:08:02 +00:00 committed by GitHub
parent d3affac417
commit 8a61985ac8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 619 additions and 144 deletions

View File

@ -1105,7 +1105,7 @@ namespace etl
#if ETL_USING_CPP17
template <typename... T>
array(T...) -> array<typename etl::common_type<T...>::type, sizeof...(T)>;
#endif
#endif
//*************************************************************************
/// Make

View File

@ -765,11 +765,11 @@ namespace etl
///\ingroup type_traits
/// Implemented by checking if type is convertible to an integer through static_cast
namespace private_type_traits
namespace private_type_traits
{
// Base case
template <typename T, typename = int>
struct is_convertible_to_int
struct is_convertible_to_int
: false_type
{
};
@ -778,7 +778,7 @@ namespace etl
// 2nd template argument of base case defaults to int to ensure that this partial specialization is always tried first
template <typename T>
struct is_convertible_to_int<T, decltype(static_cast<int>(declval<T>()))>
: true_type
: true_type
{
};
}
@ -788,7 +788,7 @@ namespace etl
: integral_constant<bool, private_type_traits::is_convertible_to_int<T>::value &&
!is_class<T>::value &&
!is_arithmetic<T>::value &&
!is_reference<T>::value>
!is_reference<T>::value>
{
};
@ -1647,7 +1647,7 @@ typedef integral_constant<bool, true> true_type;
//***************************************************************************
/// Get the Nth base of a recursively inherited type.
/// Requires that the class has defined 'base_type'.
//***************************************************************************
//***************************************************************************
// Recursive definition of the type.
template <size_t Index, typename TType>
struct nth_base
@ -2192,7 +2192,7 @@ typedef integral_constant<bool, true> true_type;
#if ETL_USING_CPP11
//***************************************************************************
/// is_constructible
namespace private_type_traits
namespace private_type_traits
{
template <class, class T, class... TArgs>
struct is_constructible_ : etl::false_type {};
@ -2371,7 +2371,7 @@ typedef integral_constant<bool, true> true_type;
};
template <typename T1, typename T2, typename = void>
struct common_type_2_impl
struct common_type_2_impl
: decay_conditional_result<const T1&, const T2&>
{
};
@ -2716,7 +2716,7 @@ typedef integral_constant<bool, true> true_type;
struct is_member_pointer_helper<T TObject::*> : etl::true_type {};
}
template<typename T>
template<typename T>
struct is_member_pointer : private_type_traits::is_member_pointer_helper<typename etl::remove_cv<T>::type> {};
#if ETL_USING_CPP17
@ -2809,10 +2809,10 @@ typedef integral_constant<bool, true> true_type;
//***************************************************************************
namespace private_type_traits
{
template<typename>
template<typename>
struct is_member_object_pointer_helper : public etl::false_type {};
template<typename T, typename TObject>
template<typename T, typename TObject>
struct is_member_object_pointer_helper<T TObject::*> : public etl::negation<etl::is_function<T>> {};
}
@ -3034,6 +3034,60 @@ typedef integral_constant<bool, true> true_type;
};
#endif
#if ETL_USING_CPP11
template <typename, typename = void>
struct has_size : etl::false_type {};
template <typename T>
struct has_size<T, void_t<decltype(etl::declval<T>().size())> >
: etl::true_type {};
#else
template <typename T>
struct has_size
{
private:
typedef char yes;
struct no { char dummy[2]; };
template <typename U>
static yes test_size(char (*)[sizeof(&U::size)]);
template <typename U>
static no test_size(...);
public:
static const bool value = (sizeof(test_size<T>(0)) == sizeof(yes));
};
#endif
#if ETL_USING_CPP11
template <typename, typename = void>
struct has_data : etl::false_type {};
template <typename T>
struct has_data<T, void_t<decltype(etl::declval<T>().data())> >
: etl::true_type {};
#else
template <typename T>
struct has_data
{
private:
typedef char yes;
struct no { char dummy[2]; };
template <typename U>
static yes test_data(char (*)[sizeof(&U::data)]);
template <typename U>
static no test_data(...);
public:
static const bool value = (sizeof(test_data<T>(0)) == sizeof(yes));
};
#endif
}
// Helper macros

View File

@ -67,7 +67,7 @@ namespace etl
typedef typename TIterator::pointer pointer;
typedef typename TIterator::reference reference;
};
// For pointers.
template <typename T>
struct iterator_traits<T*, void>
@ -606,7 +606,7 @@ namespace etl
ETL_CONSTEXPR14 back_insert_iterator& operator =(const typename TContainer::value_type& value)
{
container->push_back(value);
return (*this);
}
@ -617,7 +617,7 @@ namespace etl
ETL_CONSTEXPR14 back_insert_iterator& operator =(typename TContainer::value_type&& value)
{
container->push_back(etl::move(value));
return (*this);
}
#endif // ETL_USING_CPP11
@ -655,8 +655,8 @@ namespace etl
/// Creates a back_insert_iterator from a container.
//***************************************************************************
template <typename TContainer>
ETL_NODISCARD
ETL_CONSTEXPR14
ETL_NODISCARD
ETL_CONSTEXPR14
etl::back_insert_iterator<TContainer> back_inserter(TContainer& container)
{
return etl::back_insert_iterator<TContainer>(container);
@ -1211,6 +1211,48 @@ namespace etl
char(&array_size(T(&array)[Array_Size]))[Array_Size];
#define ETL_ARRAY_SIZE(a) sizeof(etl::array_size(a))
#if ETL_NOT_USING_STL || ETL_CPP17_NOT_SUPPORTED
//**************************************************************************
/// Returns a pointer to the block of memory containing the elements of the range.
///\ingroup container
//**************************************************************************
template<typename TContainer>
ETL_CONSTEXPR typename TContainer::pointer data(TContainer& container)
{
return container.data();
}
//**************************************************************************
/// Returns a const_pointer to the block of memory containing the elements of the range.
///\ingroup container
//**************************************************************************
template<typename TContainer>
ETL_CONSTEXPR typename TContainer::const_pointer data(const TContainer& container)
{
return container.data();
}
///**************************************************************************
/// Returns a pointer to the block of memory containing the elements of the range.
///\ingroup container
///**************************************************************************
template<typename TValue, size_t Array_Size>
ETL_CONSTEXPR TValue* data(TValue(&a)[Array_Size])
{
return a;
}
///**************************************************************************
/// Returns a const pointer to the block of memory containing the elements of the range.
///\ingroup container
///**************************************************************************
template<typename TValue, size_t Array_Size>
ETL_CONSTEXPR const TValue* data(const TValue(&a)[Array_Size])
{
return a;
}
#endif
}
#endif

View File

@ -382,11 +382,13 @@ SOFTWARE.
#if ETL_USING_EXCEPTIONS
#define ETL_NOEXCEPT noexcept
#define ETL_NOEXCEPT_EXPR(...) noexcept(__VA_ARGS__)
#define ETL_NOEXCEPT_IF(b) noexcept((b))
#define ETL_NOEXCEPT_FROM(x) noexcept(noexcept(x))
#else
#define ETL_NOEXCEPT
#define ETL_NOEXCEPT_EXPR(...)
#define ETL_NOEXCEPT_FROM(x)
#define ETL_NOEXCEPT_IF(b)
#define ETL_NOEXCEPT_FROM(x)
#endif
#else
#define ETL_CONSTEXPR
@ -399,7 +401,8 @@ SOFTWARE.
#define ETL_NORETURN
#define ETL_NOEXCEPT
#define ETL_NOEXCEPT_EXPR(...)
#define ETL_NOEXCEPT_FROM(x)
#define ETL_NOEXCEPT_IF(b)
#define ETL_NOEXCEPT_FROM(x)
#define ETL_MOVE(x) x
#define ETL_ENUM_CLASS(name) enum name
#define ETL_ENUM_CLASS_TYPE(name, type) enum name
@ -412,7 +415,7 @@ SOFTWARE.
#if ETL_USING_CPP14
#define ETL_CONSTEXPR14 constexpr
#if !defined(ETL_IN_UNIT_TEST)
#if !defined(ETL_IN_UNIT_TEST)
#define ETL_DEPRECATED [[deprecated]]
#define ETL_DEPRECATED_REASON(reason) [[deprecated(reason)]]
#else
@ -611,7 +614,7 @@ SOFTWARE.
#elif defined(ETL_COMPILER_MICROSOFT)
#define ETL_PACKED_CLASS(class_type) __pragma(pack(push, 1)) class class_type
#define ETL_PACKED_STRUCT(struct_type) __pragma(pack(push, 1)) struct struct_type
#define ETL_PACKED
#define ETL_PACKED
#define ETL_END_PACKED __pragma(pack(pop))
#define ETL_HAS_PACKED 1
#else
@ -662,7 +665,7 @@ namespace etl
static ETL_CONSTANT bool using_libc_wchar_h = (ETL_USING_LIBC_WCHAR_H == 1);
static ETL_CONSTANT bool using_std_exception = (ETL_USING_STD_EXCEPTION == 1);
static ETL_CONSTANT bool using_format_floating_point = (ETL_USING_FORMAT_FLOATING_POINT == 1);
// Has...
static ETL_CONSTANT bool has_initializer_list = (ETL_HAS_INITIALIZER_LIST == 1);
static ETL_CONSTANT bool has_8bit_types = (ETL_USING_8BIT_TYPES == 1);

View File

@ -47,6 +47,12 @@ SOFTWARE.
#include "array.h"
#include "byte.h"
#include "static_assert.h"
#include "container.h"
#include "private/tuple_size.h"
#if ETL_USING_STL && ETL_USING_CPP20
#include <span>
#endif
#include "private/dynamic_extent.h"
@ -72,7 +78,28 @@ namespace etl
//***************************************************************************
// Tag to indicate a class is a span.
//***************************************************************************
class span_tag {};
// Forward declaration for trait
template <typename T, size_t Extent>
class span;
namespace private_span
{
template <typename T>
struct is_span_helper : etl::false_type {};
template <typename T, size_t Extent>
struct is_span_helper<etl::span<T, Extent> > : etl::true_type {};
}
template <typename T>
struct is_span
: private_span::is_span_helper<typename etl::remove_cvref<T>::type> {};
#if ETL_USING_CPP17
template <typename T>
inline constexpr bool is_span_v = is_span<T>::value;
#endif
//***************************************************************************
///\ingroup span
@ -130,6 +157,12 @@ namespace etl
}
};
//***************************************************************************
///\ingroup span
/// Tag to indicate a class is a span.
/// Deprecated, use is_span trait instead.
class span_tag {};
//***************************************************************************
/// Span - Fixed Extent
//***************************************************************************
@ -141,13 +174,13 @@ namespace etl
typedef T element_type;
typedef typename etl::remove_cv<T>::type value_type;
typedef size_t size_type;
typedef T& reference;
typedef const T& const_reference;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T* pointer;
typedef const T* const_pointer;
typedef T* iterator;
typedef const T* const_iterator;
typedef T* iterator;
typedef const T* const_iterator;
typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
@ -157,72 +190,92 @@ namespace etl
static ETL_CONSTANT size_t extent = Extent;
//*************************************************************************
/// Construct from iterators + size
/// Default constructor
/// Enabled only for zero extent, creates an empty span.
//*************************************************************************
template <typename TIterator, typename TSize>
ETL_CONSTEXPR explicit span(const TIterator begin_, const TSize /*size_*/) ETL_NOEXCEPT
#if ETL_USING_CPP11
template <size_t E = Extent, typename = typename etl::enable_if<E == 0, void>::type>
ETL_CONSTEXPR span() ETL_NOEXCEPT
: pbegin(ETL_NULLPTR)
{
}
#else
ETL_CONSTEXPR span() ETL_NOEXCEPT
: pbegin(ETL_NULLPTR)
{
ETL_STATIC_ASSERT(Extent == 0, "Default constructor only available for zero extent");
}
#endif
//*************************************************************************
/// Construct from iterator + size
//*************************************************************************
template <typename TIterator>
explicit ETL_CONSTEXPR14 span(const TIterator begin_, const size_t size_) ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS)
: pbegin(etl::to_address(begin_))
{
ETL_ASSERT(size_ == Extent, ETL_ERROR(span_size_mismatch));
(void)size_;
}
//*************************************************************************
/// Construct from iterators
//*************************************************************************
template <typename TIterator>
ETL_CONSTEXPR explicit span(const TIterator begin_, const TIterator /*end_*/) ETL_NOEXCEPT
template <typename TIteratorBegin, typename TIteratorEnd>
ETL_CONSTEXPR14 span(const TIteratorBegin begin_, const TIteratorEnd end_,
typename etl::enable_if<!etl::is_integral<TIteratorEnd>::value, void>::type* = 0) ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS)
: pbegin(etl::to_address(begin_))
{
ETL_ASSERT(etl::distance(begin_, end_) == Extent, ETL_ERROR(span_size_mismatch));
(void)end_;
}
//*************************************************************************
/// Construct from C array
//*************************************************************************
#if ETL_USING_CPP11
template<size_t Array_Size, typename = typename etl::enable_if<(Array_Size == Extent), void>::type>
ETL_CONSTEXPR span(element_type(&begin_)[Array_Size]) ETL_NOEXCEPT
: pbegin(begin_)
{
}
#else
//*************************************************************************
/// Construct from C array
//*************************************************************************
template<size_t Array_Size>
ETL_CONSTEXPR span(element_type(&begin_)[Array_Size], typename etl::enable_if<(Array_Size == Extent), void>::type* = 0) ETL_NOEXCEPT
ETL_CONSTEXPR span(typename etl::type_identity<element_type>::type(&begin_)[Array_Size], typename etl::enable_if<(Array_Size == Extent), void>::type* = 0) ETL_NOEXCEPT
: pbegin(begin_)
{
}
#endif
#if ETL_USING_CPP11
//*************************************************************************
/// Construct from a container or other type that supports
/// data() and size() member functions.
//*************************************************************************
template <typename TContainer, typename = typename etl::enable_if<!etl::is_base_of<span_tag, etl::remove_reference_t<TContainer>>::value &&
!etl::is_std_array<etl::remove_reference_t<TContainer>>::value &&
!etl::is_etl_array<etl::remove_reference_t<TContainer>>::value &&
!etl::is_pointer<etl::remove_reference_t<TContainer>>::value &&
!etl::is_array<etl::remove_reference_t<TContainer>>::value &&
etl::is_same<etl::remove_cv_t<T>, etl::remove_cv_t<typename etl::remove_reference_t<TContainer>::value_type>>::value, void>::type>
ETL_CONSTEXPR span(TContainer&& a) ETL_NOEXCEPT
: pbegin(a.data())
{
}
template <typename TContainer>
ETL_CONSTEXPR14 span(TContainer&& a, typename etl::enable_if<!etl::is_span<TContainer>::value &&
!etl::is_std_array<typename etl::remove_reference<TContainer>::type>::value &&
!etl::is_etl_array<typename etl::remove_reference<TContainer>::type>::value &&
!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
!etl::is_array<TContainer>::value &&
etl::is_lvalue_reference<TContainer&&>::value &&
has_size<TContainer>::value &&
has_data<TContainer>::value &&
etl::is_convertible<decltype(etl::declval<typename etl::remove_reference<TContainer>::type&>().data()), pointer>::value &&
etl::is_same<typename etl::remove_cv<T>::type, typename etl::remove_cv<typename etl::remove_reference<TContainer>::type::value_type>::type>::value, void>::type* = 0) ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS)
: pbegin(a.data())
{
ETL_ASSERT(a.size() == Extent, ETL_ERROR(span_size_mismatch));
}
#else
//*************************************************************************
/// Construct from a container or other type that supports
/// data() and size() member functions.
//*************************************************************************
template <typename TContainer>
span(TContainer& a, typename etl::enable_if<!etl::is_base_of<span_tag, typename etl::remove_reference<TContainer>::type>::value &&
span(TContainer& a, typename etl::enable_if<!etl::is_span<TContainer>::value &&
!etl::is_std_array<typename etl::remove_reference<TContainer>::type>::value &&
!etl::is_etl_array<typename etl::remove_reference<TContainer>::type>::value &&
!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
!etl::is_array<TContainer>::value &&
etl::is_same<typename etl::remove_cv<T>::type, typename etl::remove_cv<typename etl::remove_reference<TContainer>::type::value_type>::type>::value, void>::type* = 0) ETL_NOEXCEPT
has_size<TContainer>::value &&
has_data<TContainer>::value &&
etl::is_same<typename etl::remove_cv<T>::type, typename etl::remove_cv<typename etl::remove_reference<TContainer>::type::value_type>::type>::value, void>::type* = 0)
: pbegin(a.data())
{
ETL_ASSERT(a.size() == Extent, ETL_ERROR(span_size_mismatch));
}
//*************************************************************************
@ -230,17 +283,69 @@ namespace etl
/// data() and size() member functions.
//*************************************************************************
template <typename TContainer>
span(const TContainer& a, typename etl::enable_if<!etl::is_base_of<span_tag, typename etl::remove_reference<TContainer>::type>::value &&
span(const TContainer& a, typename etl::enable_if<!etl::is_span<TContainer>::value &&
!etl::is_std_array<typename etl::remove_reference<TContainer>::type>::value &&
!etl::is_etl_array<typename etl::remove_reference<TContainer>::type>::value &&
!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
!etl::is_array<TContainer>::value&&
etl::is_same<typename etl::remove_cv<T>::type, typename etl::remove_cv<typename etl::remove_reference<TContainer>::type::value_type>::type>::value, void>::type* = 0) ETL_NOEXCEPT
has_size<TContainer>::value &&
has_data<TContainer>::value &&
etl::is_same<typename etl::remove_cv<T>::type, typename etl::remove_cv<typename etl::remove_reference<TContainer>::type::value_type>::type>::value, void>::type* = 0)
: pbegin(a.data())
{
ETL_ASSERT(a.size() == Extent, ETL_ERROR(span_size_mismatch));
}
#endif
//*************************************************************************
/// Constructor from etl array.
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR span(etl::array<U, Size>& other, typename etl::enable_if<(Size == Extent) &&
etl::is_convertible<U(*)[], T(*)[]>::value, void>::type* = 0) ETL_NOEXCEPT
: pbegin(other.data())
{
}
//*************************************************************************
/// Constructor from const etl array.
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR span(const etl::array<U, Size>& other, typename etl::enable_if<(Size == Extent) &&
etl::is_convertible<U(*)[], T(*)[]>::value, void>::type* = 0) ETL_NOEXCEPT
: pbegin(other.data())
{
}
#if ETL_USING_CPP11
template <typename U, size_t Size>
span(etl::array<U, Size>&&) = delete;
#endif
#if ETL_USING_STL && ETL_USING_CPP11
//*************************************************************************
/// Constructor from std array.
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR span(std::array<U, Size>& other, typename etl::enable_if<(Size == Extent) &&
etl::is_convertible<U(*)[], T(*)[]>::value, void>::type* = 0) ETL_NOEXCEPT
: pbegin(other.data())
{
}
//*************************************************************************
/// Constructor from const std array.
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR span(const std::array<U, Size>& other, typename etl::enable_if<(Size == Extent) &&
etl::is_convertible<U(*)[], T(*)[]>::value, void>::type* = 0) ETL_NOEXCEPT
: pbegin(other.data())
{
}
template <typename U, size_t Size>
span(std::array<U, Size>&&) = delete;
#endif
//*************************************************************************
/// Copy constructor
//*************************************************************************
@ -254,7 +359,7 @@ namespace etl
/// From fixed extent span.
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR span(const etl::span<U, Size>& other, typename etl::enable_if<Size == Extent, void>::type* = 0) ETL_NOEXCEPT
ETL_CONSTEXPR span(const etl::span<U, Size>& other, typename etl::enable_if<(Size == Extent) && (Size != etl::dynamic_extent), void>::type* = 0) ETL_NOEXCEPT
: pbegin(other.data())
{
}
@ -264,50 +369,37 @@ namespace etl
/// From dynamic extent span.
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR14 span(const etl::span<U, Size>& other, typename etl::enable_if<Size == etl::dynamic_extent, void>::type* = 0)
ETL_CONSTEXPR14 explicit span(const etl::span<U, Size>& other, typename etl::enable_if<(Size == etl::dynamic_extent), void>::type* = 0)
: pbegin(other.data())
{
ETL_ASSERT(other.size() == Extent, ETL_ERROR(span_size_mismatch));
}
#if ETL_USING_STL && ETL_USING_CPP11
#if ETL_USING_STL && ETL_USING_CPP20
//*************************************************************************
/// Constructor from std array.
/// Copy constructor
/// From fixed extent std::span.
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR span(std::array<U, Size>& other, typename etl::enable_if<Size == Extent, void>::type* = 0) ETL_NOEXCEPT
ETL_CONSTEXPR span(const std::span<U, Size>& other, typename etl::enable_if<(Size == Extent) &&
etl::is_convertible<U(*)[], T(*)[]>::value, int>::type* = 0) ETL_NOEXCEPT
: pbegin(other.data())
{
}
//*************************************************************************
/// Constructor from const std array.
/// Copy constructor
/// From dynamic extent std::span.
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR span(const std::array<U, Size>& other, typename etl::enable_if<Size == Extent && etl::is_const<T>::value, void>::type* = 0) ETL_NOEXCEPT
ETL_CONSTEXPR14 span(const std::span<U, Size>& other, typename etl::enable_if<(Size == etl::dynamic_extent &&
etl::is_convertible<U(*)[], T(*)[]>::value), int>::type* = 0) ETL_NOEXCEPT
: pbegin(other.data())
{
ETL_ASSERT(other.size() == Extent, ETL_ERROR(span_size_mismatch));
}
#endif
//*************************************************************************
/// Constructor from etl array.
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR span(etl::array<U, Size>& other, typename etl::enable_if<Size == Extent, void>::type* = 0) ETL_NOEXCEPT
: pbegin(other.data())
{
}
//*************************************************************************
/// Constructor from const etl array.
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR span(const etl::array<U, Size>& other, typename etl::enable_if<Size == Extent && etl::is_const<T>::value, void>::type* = 0) ETL_NOEXCEPT
: pbegin(other.data())
{
}
//*************************************************************************
/// Returns a reference to the first element.
//*************************************************************************
@ -455,7 +547,7 @@ namespace etl
{
pbegin = other.pbegin;
return *this;
}
}
//*************************************************************************
/// Returns a reference to the value at index 'i'.
@ -506,13 +598,13 @@ namespace etl
//*************************************************************************
/// Obtains a span that is a view over the first count elements of this span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, etl::dynamic_extent> first(size_t count) const ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, etl::dynamic_extent> first(size_t count) const ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
{
#if ETL_USING_CPP11 && ETL_NOT_USING_CPP14 && ETL_USING_EXCEPTIONS && ETL_CHECKING_EXTRA
return count <= size() ? etl::span<element_type, etl::dynamic_extent>(pbegin, pbegin + count) : throw(ETL_ERROR(span_out_of_range));
#else
ETL_ASSERT_CHECK_EXTRA(count <= size(), ETL_ERROR(span_out_of_range));
return etl::span<element_type, etl::dynamic_extent>(pbegin, pbegin + count);
#endif
}
@ -532,11 +624,11 @@ namespace etl
//*************************************************************************
/// Obtains a span that is a view over the last count elements of this span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, etl::dynamic_extent> last(size_t count) const ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, etl::dynamic_extent> last(size_t count) const ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
{
#if ETL_USING_CPP11 && ETL_NOT_USING_CPP14 && ETL_USING_EXCEPTIONS && ETL_CHECKING_EXTRA
return count <= size() ?
etl::span<element_type, etl::dynamic_extent>((pbegin + Extent) - count, (pbegin + Extent)) :
return count <= size() ?
etl::span<element_type, etl::dynamic_extent>((pbegin + Extent) - count, (pbegin + Extent)) :
throw(ETL_ERROR(span_out_of_range));
#else
ETL_ASSERT_CHECK_EXTRA(count <= size(), ETL_ERROR(span_out_of_range));
@ -589,7 +681,7 @@ namespace etl
//*************************************************************************
/// Obtains a span that is a view from 'offset' over the next 'count' elements of this span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, etl::dynamic_extent> subspan(size_t offset, size_t count = etl::dynamic_extent) const ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, etl::dynamic_extent> subspan(size_t offset, size_t count = etl::dynamic_extent) const ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
{
#if ETL_USING_CPP11 && ETL_NOT_USING_CPP14 && ETL_USING_EXCEPTIONS && ETL_CHECKING_EXTRA
return (offset <= size()) && (count != etl::dynamic_extent ? count <= (size() - offset) : true) ?
@ -636,7 +728,7 @@ namespace etl
/// Span - Dynamic Extent
//***************************************************************************
template <typename T>
class span<T, etl::dynamic_extent> : public span_tag
class span<T, etl::dynamic_extent> : public span_tag
{
public:
@ -668,10 +760,10 @@ namespace etl
}
//*************************************************************************
/// Construct from pointer + size
/// Construct from iterator + size
//*************************************************************************
template <typename TIterator, typename TSize>
ETL_CONSTEXPR span(const TIterator begin_, const TSize size_) ETL_NOEXCEPT
template <typename TIterator>
ETL_CONSTEXPR span(const TIterator begin_, size_t size_) ETL_NOEXCEPT
: pbegin(etl::to_address(begin_))
, pend(etl::to_address(begin_) + size_)
{
@ -680,8 +772,9 @@ namespace etl
//*************************************************************************
/// Construct from iterators
//*************************************************************************
template <typename TIterator>
ETL_CONSTEXPR span(const TIterator begin_, const TIterator end_) ETL_NOEXCEPT
template <typename TIteratorBegin, typename TIteratorEnd>
ETL_CONSTEXPR span(const TIteratorBegin begin_, const TIteratorEnd end_,
typename etl::enable_if<!etl::is_integral<TIteratorEnd>::value, void>::type* = 0) ETL_NOEXCEPT
: pbegin(etl::to_address(begin_))
, pend(etl::to_address(begin_) + etl::distance(begin_, end_))
{
@ -702,11 +795,17 @@ namespace etl
/// Construct from a container or other type that supports
/// data() and size() member functions.
//*************************************************************************
template <typename TContainer, typename = typename etl::enable_if<!etl::is_base_of<span_tag, etl::remove_reference_t<TContainer>>::value &&
!etl::is_pointer<etl::remove_reference_t<TContainer>>::value &&
!etl::is_array<etl::remove_reference_t<TContainer>>::value &&
etl::is_same<etl::remove_cv_t<T>, etl::remove_cv_t<typename etl::remove_reference_t<TContainer>::value_type>>::value, void>::type>
ETL_CONSTEXPR span(TContainer&& a) ETL_NOEXCEPT
template <typename TContainer>
ETL_CONSTEXPR span(TContainer&& a, typename etl::enable_if<!etl::is_span<TContainer>::value &&
!etl::is_std_array<typename etl::remove_reference<TContainer>::type>::value &&
!etl::is_etl_array<typename etl::remove_reference<TContainer>::type>::value &&
!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
!etl::is_array<TContainer>::value &&
etl::is_lvalue_reference<TContainer&&>::value &&
has_size<TContainer>::value &&
has_data<TContainer>::value &&
etl::is_convertible<decltype(etl::declval<typename etl::remove_reference<TContainer>::type&>().data()), pointer>::value &&
etl::is_same<typename etl::remove_cv<T>::type, typename etl::remove_cv<typename etl::remove_reference<TContainer>::type::value_type>::type>::value, void>::type* = 0) ETL_NOEXCEPT
: pbegin(a.data())
, pend(a.data() + a.size())
{
@ -717,10 +816,14 @@ namespace etl
/// data() and size() member functions.
//*************************************************************************
template <typename TContainer>
ETL_CONSTEXPR span(TContainer& a, typename etl::enable_if<!etl::is_base_of<span_tag, typename etl::remove_reference<TContainer>::type>::value &&
!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
!etl::is_array<TContainer>::value &&
etl::is_same<typename etl::remove_cv<T>::type, typename etl::remove_cv<typename etl::remove_reference<TContainer>::type::value_type>::type>::value, void>::type* = 0) ETL_NOEXCEPT
span(TContainer& a, typename etl::enable_if<!etl::is_span<TContainer>::value &&
!etl::is_std_array<typename etl::remove_reference<TContainer>::type>::value &&
!etl::is_etl_array<typename etl::remove_reference<TContainer>::type>::value &&
!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
!etl::is_array<TContainer>::value &&
has_size<TContainer>::value &&
has_data<TContainer>::value &&
etl::is_same<typename etl::remove_cv<T>::type, typename etl::remove_cv<typename etl::remove_reference<TContainer>::type::value_type>::type>::value, void>::type* = 0) ETL_NOEXCEPT
: pbegin(a.data())
, pend(a.data() + a.size())
{
@ -731,16 +834,92 @@ namespace etl
/// data() and size() member functions.
//*************************************************************************
template <typename TContainer>
ETL_CONSTEXPR span(const TContainer& a, typename etl::enable_if<!etl::is_base_of<span_tag, typename etl::remove_reference<TContainer>::type>::value &&
!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
!etl::is_array<TContainer>::value &&
etl::is_same<typename etl::remove_cv<T>::type, typename etl::remove_cv<typename etl::remove_reference<TContainer>::type::value_type>::type>::value, void>::type* = 0) ETL_NOEXCEPT
span(const TContainer& a, typename etl::enable_if<!etl::is_span<TContainer>::value &&
!etl::is_std_array<typename etl::remove_reference<TContainer>::type>::value &&
!etl::is_etl_array<typename etl::remove_reference<TContainer>::type>::value &&
!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
!etl::is_array<TContainer>::value &&
has_size<TContainer>::value &&
has_data<TContainer>::value &&
etl::is_same<typename etl::remove_cv<T>::type, typename etl::remove_cv<typename etl::remove_reference<TContainer>::type::value_type>::type>::value, void>::type* = 0) ETL_NOEXCEPT
: pbegin(a.data())
, pend(a.data() + a.size())
{
}
#endif
#if ETL_USING_STL && ETL_USING_CPP20
//*************************************************************************
/// Constructor from std span.
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR span(std::span<U, Size>& other, typename etl::enable_if<etl::is_convertible<U(*)[], T(*)[]>::value, int>::type* = 0) ETL_NOEXCEPT
: pbegin(other.data())
, pend(other.data() + other.size())
{
}
//*************************************************************************
/// Constructor from const std span.
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR span(const std::span<U, Size>& other, typename etl::enable_if<etl::is_convertible<U(*)[], T(*)[]>::value, int>::type* = 0) ETL_NOEXCEPT
: pbegin(other.data())
, pend(other.data() + other.size())
{
}
#endif
//*************************************************************************
/// Constructor from etl array.
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR span(etl::array<U, Size>& other, typename etl::enable_if<etl::is_convertible<U(*)[], T(*)[]>::value, void>::type* = 0) ETL_NOEXCEPT
: pbegin(other.data()),
pend(other.data() + Size)
{
}
//*************************************************************************
/// Constructor from const etl array.
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR span(const etl::array<U, Size>& other, typename etl::enable_if<etl::is_convertible<U(*)[], T(*)[]>::value, void>::type* = 0) ETL_NOEXCEPT
: pbegin(other.data()),
pend(other.data() + Size)
{
}
#if ETL_USING_CPP11
template <typename U, size_t Size>
span(etl::array<U, Size>&&) = delete;
#endif
#if ETL_USING_STL && ETL_USING_CPP11
//*************************************************************************
/// Constructor from std array.
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR span(std::array<U, Size>& other, typename etl::enable_if<etl::is_convertible<U(*)[], T(*)[]>::value, void>::type* = 0) ETL_NOEXCEPT
: pbegin(other.data()),
pend(other.data() + Size)
{
}
//*************************************************************************
/// Constructor from const std array.
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR span(const std::array<U, Size>& other, typename etl::enable_if<etl::is_convertible<U(*)[], T(*)[]>::value, void>::type* = 0) ETL_NOEXCEPT
: pbegin(other.data()),
pend(other.data() + Size)
{
}
template <typename U, size_t Size>
span(std::array<U, Size>&&) = delete;
#endif
//*************************************************************************
/// Copy constructor
//*************************************************************************
@ -763,7 +942,7 @@ namespace etl
//*************************************************************************
/// Returns a reference to the first element.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
{
#if ETL_USING_CPP11 && ETL_NOT_USING_CPP14 && ETL_USING_EXCEPTIONS && ETL_CHECKING_EXTRA
return size() > 0 ? *pbegin : throw(ETL_ERROR(span_out_of_range));
@ -777,7 +956,7 @@ namespace etl
//*************************************************************************
/// Returns a reference to the last element.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
{
#if ETL_USING_CPP11 && ETL_NOT_USING_CPP14 && ETL_USING_EXCEPTIONS && ETL_CHECKING_EXTRA
return size() > 0 ? *(pend - 1) : throw(ETL_ERROR(span_out_of_range));
@ -956,7 +1135,7 @@ namespace etl
/// Obtains a span that is a view over the first COUNT elements of this span.
//*************************************************************************
template <size_t COUNT>
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, COUNT> first() const ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, COUNT> first() const ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
{
#if ETL_USING_CPP11 && ETL_NOT_USING_CPP14 && ETL_USING_EXCEPTIONS && ETL_CHECKING_EXTRA
return COUNT <= size() ? etl::span<element_type, COUNT>(pbegin, pbegin + COUNT) : throw(ETL_ERROR(span_out_of_range));
@ -970,7 +1149,7 @@ namespace etl
//*************************************************************************
/// Obtains a span that is a view over the first count elements of this span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, etl::dynamic_extent> first(size_t count) const ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, etl::dynamic_extent> first(size_t count) const ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
{
#if ETL_USING_CPP11 && ETL_NOT_USING_CPP14 && ETL_USING_EXCEPTIONS && ETL_CHECKING_EXTRA
return count <= size() ? etl::span<element_type, etl::dynamic_extent>(pbegin, pbegin + count) : throw(ETL_ERROR(span_out_of_range));
@ -985,7 +1164,7 @@ namespace etl
/// Obtains a span that is a view over the last COUNT elements of this span.
//*************************************************************************
template <size_t COUNT>
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, COUNT> last() const ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, COUNT> last() const ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
{
#if ETL_USING_CPP11 && ETL_NOT_USING_CPP14 && ETL_USING_EXCEPTIONS && ETL_CHECKING_EXTRA
return COUNT <= size() ? etl::span<element_type, COUNT>(pend - COUNT, pend) : throw(ETL_ERROR(span_out_of_range));
@ -999,7 +1178,7 @@ namespace etl
//*************************************************************************
/// Obtains a span that is a view over the last count elements of this span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, etl::dynamic_extent> last(size_t count) const ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, etl::dynamic_extent> last(size_t count) const ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
{
#if ETL_USING_CPP11 && ETL_NOT_USING_CPP14 && ETL_USING_EXCEPTIONS && ETL_CHECKING_EXTRA
return count <= size() ? etl::span<element_type, etl::dynamic_extent>(pend - count, pend) : throw(ETL_ERROR(span_out_of_range));
@ -1016,7 +1195,7 @@ namespace etl
//*************************************************************************
template <size_t OFFSET, size_t COUNT = etl::dynamic_extent>
ETL_NODISCARD ETL_CONSTEXPR
etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent> subspan() const ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent> subspan() const ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
{
#if ETL_USING_CPP11 && ETL_NOT_USING_CPP14 && ETL_USING_EXCEPTIONS && ETL_CHECKING_EXTRA
return (OFFSET <= size()) && (COUNT != etl::dynamic_extent ? COUNT <= (size() - OFFSET) : true) ?
@ -1055,7 +1234,7 @@ namespace etl
//*************************************************************************
/// Obtains a span that is a view from 'offset' over the next 'count' elements of this span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR14 etl::span<element_type, etl::dynamic_extent> subspan(size_t offset, size_t count = etl::dynamic_extent) const ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
ETL_NODISCARD ETL_CONSTEXPR14 etl::span<element_type, etl::dynamic_extent> subspan(size_t offset, size_t count = etl::dynamic_extent) const ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
{
ETL_ASSERT_CHECK_EXTRA(offset <= size(), ETL_ERROR(span_out_of_range));
ETL_ASSERT_CHECK_EXTRA(count != etl::dynamic_extent ? count <= (size() - offset) : true, ETL_ERROR(span_out_of_range));
@ -1161,7 +1340,7 @@ namespace etl
/// Compare two spans for equality.
//*************************************************************************
template <typename T1, size_t N1, typename T2, size_t N2>
ETL_NODISCARD
ETL_NODISCARD
ETL_CONSTEXPR
typename etl::enable_if<etl::is_same<typename etl::remove_cv<T1>::type, typename etl::remove_cv<T2>::type>::value, bool>::type
operator ==(const etl::span<T1, N1>& lhs, const etl::span<T2, N2>& rhs) ETL_NOEXCEPT
@ -1255,7 +1434,7 @@ namespace etl
template<typename T>
span(etl::ivector<T>&)
-> span<T>;
template<typename T>
span(const etl::ivector<T>&)
-> span<const T>;
@ -1269,7 +1448,7 @@ namespace etl
span(const std::array<T, Size>&)
->span<const T, Size>;
#endif
#endif
#endif
//*************************************************************************
/// Hash function.
@ -1290,7 +1469,7 @@ namespace etl
/// Obtains a view to the byte representation of the elements of the span s.
//*************************************************************************
template <class T, size_t Size>
span<const byte, (Size == etl::dynamic_extent) ? (etl::dynamic_extent) : (Size * sizeof(T))>
span<const byte, (Size == etl::dynamic_extent) ? (etl::dynamic_extent) : (Size * sizeof(T))>
as_bytes(span<T, Size> s) ETL_NOEXCEPT
{
return span<const byte, (Size == etl::dynamic_extent) ? (etl::dynamic_extent) : (Size * sizeof(T))>(reinterpret_cast<const byte*>(s.data()), s.size_bytes());
@ -1300,7 +1479,7 @@ namespace etl
/// Obtains a view to the byte representation of the elements of the span s.
//*************************************************************************
template <class T, size_t Size>
span<byte, (Size == etl::dynamic_extent) ? (etl::dynamic_extent) : (Size * sizeof(T))>
span<byte, (Size == etl::dynamic_extent) ? (etl::dynamic_extent) : (Size * sizeof(T))>
as_writable_bytes(span<T, Size> s) ETL_NOEXCEPT
{
ETL_STATIC_ASSERT(!etl::is_const<T>::value, "span<T> must be of non-const type");

View File

@ -753,11 +753,11 @@ namespace etl
///\ingroup type_traits
/// Implemented by checking if type is convertible to an integer through static_cast
namespace private_type_traits
namespace private_type_traits
{
// Base case
template <typename T, typename = int>
struct is_convertible_to_int
struct is_convertible_to_int
: false_type
{
};
@ -766,7 +766,7 @@ namespace etl
// 2nd template argument of base case defaults to int to ensure that this partial specialization is always tried first
template <typename T>
struct is_convertible_to_int<T, decltype(static_cast<int>(declval<T>()))>
: true_type
: true_type
{
};
}
@ -776,7 +776,7 @@ namespace etl
: integral_constant<bool, private_type_traits::is_convertible_to_int<T>::value &&
!is_class<T>::value &&
!is_arithmetic<T>::value &&
!is_reference<T>::value>
!is_reference<T>::value>
{
};
@ -860,6 +860,42 @@ namespace etl
public:
static ETL_CONSTANT bool value = decltype(test<TFrom>(0))::value;
};
#else
namespace private_type_traits
{
typedef char yes;
struct no { char dummy[2]; };
template <typename TFrom, typename TTo>
struct is_convertible_impl
{
static yes test(TTo);
static no test(...);
static TFrom make();
static const bool value = (sizeof(test(make())) == sizeof(yes));
};
template <typename TTo>
struct is_convertible_impl<void, TTo>
{
static const bool value = false;
};
template <typename TFrom>
struct is_convertible_impl<TFrom, void>
{
static const bool value = false;
};
template <>
struct is_convertible_impl<void, void>
{
static const bool value = true;
};
}
template <typename TFrom, typename TTo>
struct is_convertible : etl::bool_constant<private_type_traits::is_convertible_impl<TFrom, TTo>::value> {};
#endif
#if ETL_USING_CPP17
@ -1408,6 +1444,42 @@ typedef integral_constant<bool, true> true_type;
public:
static ETL_CONSTANT bool value = decltype(test<TFrom>(0))::value;
};
#else
namespace private_type_traits
{
typedef char yes;
struct no { char dummy[2]; };
template <typename TFrom, typename TTo>
struct is_convertible_impl
{
static yes test(TTo);
static no test(...);
static TFrom make();
static const bool value = (sizeof(test(make())) == sizeof(yes));
};
template <typename TTo>
struct is_convertible_impl<void, TTo>
{
static const bool value = false;
};
template <typename TFrom>
struct is_convertible_impl<TFrom, void>
{
static const bool value = false;
};
template <>
struct is_convertible_impl<void, void>
{
static const bool value = true;
};
}
template <typename TFrom, typename TTo>
struct is_convertible : etl::bool_constant<private_type_traits::is_convertible_impl<TFrom, TTo>::value> {};
#endif
#if ETL_USING_CPP17
@ -1542,13 +1614,13 @@ typedef integral_constant<bool, true> true_type;
/// Template to determine if a type is one of a specified list.
///\ingroup types
template <typename T,
typename T1, typename T2 = void, typename T3 = void, typename T4 = void,
typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void,
typename T9 = void, typename T10 = void, typename T11 = void, typename T12 = void,
typename T1, typename T2 = void, typename T3 = void, typename T4 = void,
typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void,
typename T9 = void, typename T10 = void, typename T11 = void, typename T12 = void,
typename T13 = void, typename T14 = void, typename T15 = void, typename T16 = void>
struct is_one_of
{
static const bool value =
static const bool value =
etl::is_same<T, T1>::value ||
etl::is_same<T, T2>::value ||
etl::is_same<T, T3>::value ||
@ -1640,7 +1712,7 @@ typedef integral_constant<bool, true> true_type;
//***************************************************************************
/// Get the Nth base of a recursively inherited type.
/// Requires that the class has defined 'base_type'.
//***************************************************************************
//***************************************************************************
// Recursive definition of the type.
template <size_t Index, typename TType>
struct nth_base
@ -2185,7 +2257,7 @@ typedef integral_constant<bool, true> true_type;
#if ETL_USING_CPP11
//***************************************************************************
/// is_constructible
namespace private_type_traits
namespace private_type_traits
{
template <class, class T, class... TArgs>
struct is_constructible_ : etl::false_type {};
@ -2364,7 +2436,7 @@ typedef integral_constant<bool, true> true_type;
};
template <typename T1, typename T2, typename = void>
struct common_type_2_impl
struct common_type_2_impl
: decay_conditional_result<const T1&, const T2&>
{
};
@ -2709,7 +2781,7 @@ typedef integral_constant<bool, true> true_type;
struct is_member_pointer_helper<T TObject::*> : etl::true_type {};
}
template<typename T>
template<typename T>
struct is_member_pointer : private_type_traits::is_member_pointer_helper<typename etl::remove_cv<T>::type> {};
#if ETL_USING_CPP17
@ -2802,10 +2874,10 @@ typedef integral_constant<bool, true> true_type;
//***************************************************************************
namespace private_type_traits
{
template<typename>
template<typename>
struct is_member_object_pointer_helper : public etl::false_type {};
template<typename T, typename TObject>
template<typename T, typename TObject>
struct is_member_object_pointer_helper<T TObject::*> : public etl::negation<etl::is_function<T>> {};
}
@ -3027,6 +3099,60 @@ typedef integral_constant<bool, true> true_type;
};
#endif
#if ETL_USING_CPP11
template <typename, typename = void>
struct has_size : etl::false_type {};
template <typename T>
struct has_size<T, void_t<decltype(etl::declval<T>().size())> >
: etl::true_type {};
#else
template <typename T>
struct has_size
{
private:
typedef char yes;
struct no { char dummy[2]; };
template <typename U>
static yes test_size(char (*)[sizeof(&U::size)]);
template <typename U>
static no test_size(...);
public:
static const bool value = (sizeof(test_size<T>(0)) == sizeof(yes));
};
#endif
#if ETL_USING_CPP11
template <typename, typename = void>
struct has_data : etl::false_type {};
template <typename T>
struct has_data<T, void_t<decltype(etl::declval<T>().data())> >
: etl::true_type {};
#else
template <typename T>
struct has_data
{
private:
typedef char yes;
struct no { char dummy[2]; };
template <typename U>
static yes test_data(char (*)[sizeof(&U::data)]);
template <typename U>
static no test_data(...);
public:
static const bool value = (sizeof(test_data<T>(0)) == sizeof(yes));
};
#endif
}
// Helper macros

View File

@ -31,6 +31,7 @@ SOFTWARE.
#include "etl/container.h"
#include <list>
#include <vector>
#if ETL_NOT_USING_STL
@ -145,6 +146,34 @@ namespace
size_t compiletime_size = sizeof(etl::array_size(data));
CHECK_EQUAL(SIZE, compiletime_size);
}
//*************************************************************************
TEST(test_stl_style_container_data)
{
const size_t SIZE = 10UL;
std::vector<int> data(SIZE);
const std::vector<int> cdata(SIZE);
int* pdata = ETL_OR_STD17::data(data);
const int* pcdata = ETL_OR_STD17::data(cdata);
CHECK(data.data() == pdata);
CHECK(cdata.data() == pcdata);
}
//*************************************************************************
TEST(test_c_array_data)
{
const size_t SIZE = 10UL;
int data[SIZE];
const int cdata[SIZE] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int* pdata = ETL_OR_STD17::data(data);
const int* pcdata = ETL_OR_STD17::data(cdata);
CHECK(&data[0] == pdata);
CHECK(&cdata[0] == pcdata);
}
}
}

View File

@ -1627,5 +1627,23 @@ namespace
}
#include "etl/private/diagnostic_pop.h"
//*************************************************************************
TEST(test_not_constructible_from_rvalue_container)
{
#if ETL_USING_CPP17
CHECK(!(etl::is_constructible_v<View, StlVData&&>));
CHECK(!(etl::is_constructible_v<CView, StlVData&&>));
CHECK(!(etl::is_constructible_v<View, EtlData&&>));
CHECK(!(etl::is_constructible_v<View, StlData&&>));
#else
CHECK(!(etl::is_constructible<View, StlVData&&>::value));
CHECK(!(etl::is_constructible<CView, StlVData&&>::value));
CHECK(!(etl::is_constructible<View, EtlData&&>::value));
CHECK(!(etl::is_constructible<View, StlData&&>::value));
#endif
}
}
}

View File

@ -496,13 +496,19 @@ namespace
//*************************************************************************
TEST(test_empty)
{
View view1(etldata.begin(), etldata.begin());
CHECK(!view1.empty());
EView view2(etldata.begin(), etldata.begin());
CHECK(view2.empty());
}
//*************************************************************************
TEST(test_construction_from_mismatched_size)
{
CHECK_THROW((View(etldata.begin(), etldata.begin())), etl::span_size_mismatch);
CHECK_THROW((View(etldata.begin(), 1)), etl::span_size_mismatch);
CHECK_THROW((View(etldata.begin(), etldata.size() - 1)), etl::span_size_mismatch);
CHECK_THROW((View(etldata.begin(), etldata.size() + 1)), etl::span_size_mismatch);
}
//*************************************************************************
TEST(test_size)
{
@ -664,7 +670,7 @@ namespace
CHECK_EQUAL(sub1.size(), cspan1.extent);
CHECK_EQUAL(sub1.size(), cspan1.size());
auto span2 = view.subspan<2>();
auto span2 = view.subspan<2>();
isEqual = std::equal(sub2.begin(), sub2.end(), span2.begin());
CHECK(isEqual);
CHECK_EQUAL(span2.size(), span2.extent);
@ -804,7 +810,7 @@ namespace
//*************************************************************************
#include "etl/private/diagnostic_unused_function_push.h"
struct C_issue_482 {};
void f_issue_482(etl::span<char>)
@ -1220,7 +1226,7 @@ namespace
etl::span<int, 5> span2(span1);
//etl::span<int, 10> span3(span1); // This line should fail to compile.
}
//*************************************************************************
TEST(test_reinterpret_as)
{
@ -1306,5 +1312,23 @@ namespace
}
#include "etl/private/diagnostic_pop.h"
//*************************************************************************
TEST(test_not_constructible_from_rvalue_container)
{
#if ETL_USING_CPP17
CHECK(!(etl::is_constructible_v<View, StlVData&&>));
CHECK(!(etl::is_constructible_v<CView, StlVData&&>));
CHECK(!(etl::is_constructible_v<View, EtlData&&>));
CHECK(!(etl::is_constructible_v<View, StlData&&>));
#else
CHECK(!(etl::is_constructible<View, StlVData&&>::value));
CHECK(!(etl::is_constructible<CView, StlVData&&>::value));
CHECK(!(etl::is_constructible<View, EtlData&&>::value));
CHECK(!(etl::is_constructible<View, StlData&&>::value));
#endif
}
}
}