Skip to content

Commit 077518f

Browse files
author
John Wellbelove
committed
Added ETL_ASSERT for copy construction of dynamic span to fixed span
Asserts if the sizes are not equal
1 parent 9953c4d commit 077518f

File tree

2 files changed

+59
-5
lines changed

2 files changed

+59
-5
lines changed

include/etl/span.h

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,20 @@ namespace etl
9090
}
9191
};
9292

93+
//***************************************************************************
94+
///\ingroup span
95+
/// span size exception.
96+
//***************************************************************************
97+
class span_size_mismatch : public span_exception
98+
{
99+
public:
100+
101+
span_size_mismatch(string_type file_name_, numeric_type line_number_)
102+
: span_exception(ETL_ERROR_TEXT("span:size", ETL_SPAN_FILE_ID"B"), file_name_, line_number_)
103+
{
104+
}
105+
};
106+
93107
//***************************************************************************
94108
/// Span - Fixed Extent
95109
//***************************************************************************
@@ -137,11 +151,22 @@ namespace etl
137151
//*************************************************************************
138152
/// Construct from C array
139153
//*************************************************************************
140-
template<size_t Array_Size, typename = typename etl::enable_if<(Extent == etl::dynamic_extent) || (Array_Size == Extent), void>::type>
154+
#if ETL_USING_CPP11
155+
template<size_t Array_Size, typename = typename etl::enable_if<(Array_Size == Extent), void>::type>
141156
ETL_CONSTEXPR span(element_type(&begin_)[Array_Size]) ETL_NOEXCEPT
142157
: pbegin(begin_)
143158
{
144159
}
160+
#else
161+
//*************************************************************************
162+
/// Construct from C array
163+
//*************************************************************************
164+
template<size_t Array_Size>
165+
ETL_CONSTEXPR span(element_type(&begin_)[Array_Size], typename etl::enable_if<(Array_Size == Extent), void>::type* = 0) ETL_NOEXCEPT
166+
: pbegin(begin_)
167+
{
168+
}
169+
#endif
145170

146171
#if ETL_USING_CPP11
147172
//*************************************************************************
@@ -194,11 +219,23 @@ namespace etl
194219

195220
//*************************************************************************
196221
/// Copy constructor
222+
/// From fixed extent span.
223+
//*************************************************************************
224+
template <typename U, size_t N>
225+
ETL_CONSTEXPR span(const etl::span<U, N>& other, typename etl::enable_if<N == Extent, void>::type* = 0) ETL_NOEXCEPT
226+
: pbegin(other.data())
227+
{
228+
}
229+
230+
//*************************************************************************
231+
/// Copy constructor
232+
/// From dynamic extent span.
197233
//*************************************************************************
198234
template <typename U, size_t N>
199-
ETL_CONSTEXPR span(const etl::span<U, N>& other, typename etl::enable_if<(Extent == etl::dynamic_extent) || (N == etl::dynamic_extent) || (N == Extent), void>::type* = 0) ETL_NOEXCEPT
235+
ETL_CONSTEXPR span(const etl::span<U, N>& other, typename etl::enable_if<N == etl::dynamic_extent, void>::type* = 0)
200236
: pbegin(other.data())
201237
{
238+
ETL_ASSERT(other.size() == Extent, ETL_ERROR(span_size_mismatch));
202239
}
203240

204241
//*************************************************************************
@@ -505,7 +542,7 @@ namespace etl
505542
/// Span - Dynamic Extent
506543
//***************************************************************************
507544
template <typename T>
508-
class span<T, etl::dynamic_extent>
545+
class span<T, etl::dynamic_extent> : public span_tag
509546
{
510547
public:
511548

@@ -586,7 +623,8 @@ namespace etl
586623
/// data() and size() member functions.
587624
//*************************************************************************
588625
template <typename TContainer>
589-
ETL_CONSTEXPR span(TContainer& a, typename etl::enable_if<!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
626+
ETL_CONSTEXPR span(TContainer& a, typename etl::enable_if<!etl::is_base_of<span_tag, typename etl::remove_reference<TContainer>::type>::value &&
627+
!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
590628
!etl::is_array<TContainer>::value &&
591629
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
592630
: pbegin(a.data())
@@ -599,7 +637,8 @@ namespace etl
599637
/// data() and size() member functions.
600638
//*************************************************************************
601639
template <typename TContainer>
602-
ETL_CONSTEXPR span(const TContainer& a, typename etl::enable_if<!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
640+
ETL_CONSTEXPR span(const TContainer& a, typename etl::enable_if<!etl::is_base_of<span_tag, typename etl::remove_reference<TContainer>::type>::value &&
641+
!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
603642
!etl::is_array<TContainer>::value &&
604643
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
605644
: pbegin(a.data())

test/test_span_fixed_extent.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1245,6 +1245,21 @@ namespace
12451245
}
12461246
}
12471247

1248+
//*************************************************************************
1249+
TEST(test_dynamic_span_to_larger_fixed_span)
1250+
{
1251+
int data[5] = { 0, 1, 2, 3, 4 };
1252+
etl::span<int> sp1(data);
1253+
1254+
using span_4 = etl::span<int, 4>;
1255+
using span_5 = etl::span<int, 5>;
1256+
using span_8 = etl::span<int, 8>;
1257+
1258+
CHECK_NO_THROW({ span_5 sp2(sp1); });
1259+
CHECK_THROW({ span_4 sp3(sp1); }, etl::span_size_mismatch);
1260+
CHECK_THROW({ span_8 sp4(sp1); }, etl::span_size_mismatch);
1261+
}
1262+
12481263
#include "etl/private/diagnostic_pop.h"
12491264
};
12501265
}

0 commit comments

Comments
 (0)