Fixed compilation issues with Clang and GCC on Linux.

This commit is contained in:
Neil MacIntosh 2015-09-14 21:26:17 +00:00
parent 17ed5c3664
commit ef6cc65053
3 changed files with 141 additions and 177 deletions

View File

@ -290,7 +290,8 @@ public:
} }
_CONSTEXPR static index shift_left(const index<rank+1, value_type>& other) _NOEXCEPT _CONSTEXPR static index shift_left(const index<rank+1, value_type>& other) _NOEXCEPT
{ {
return (value_type(&)[rank])other.elems[1]; value_type (&arr)[rank] = (value_type(&)[rank])(*(other.elems + 1));
return index(arr);
} }
using Base::operator[]; using Base::operator[];
@ -1647,7 +1648,8 @@ public:
using typename Base::index_type; using typename Base::index_type;
using typename Base::iterator; using typename Base::iterator;
using typename Base::const_iterator; using typename Base::const_iterator;
using Base::rank; using typename Base::reference;
using Base::rank;
public: public:
// basic // basic
@ -1848,14 +1850,16 @@ public:
// section // section
_CONSTEXPR strided_array_view<ValueTypeOpt, rank> section(index_type origin, index_type extents) const _CONSTEXPR strided_array_view<ValueTypeOpt, rank> section(index_type origin, index_type extents) const
{ {
size_type size = bounds().total_size() - bounds().linearize(origin); size_type size = this->bounds().total_size() - this->bounds().linearize(origin);
return{ &this->operator[](origin), size, strided_bounds<rank, size_type> {extents, details::make_stride(Base::bounds())} }; return{ &this->operator[](origin), size, strided_bounds<rank, size_type> {extents, details::make_stride(Base::bounds())} };
} }
_CONSTEXPR reference operator[](const index_type& idx) const
_CONSTEXPR reference operator[](const index_type& idx) const
{ {
return Base::operator[](idx); return Base::operator[](idx);
} }
template <bool Enabled = (rank > 1), typename Dummy = std::enable_if_t<Enabled>>
template <bool Enabled = (rank > 1), typename Dummy = std::enable_if_t<Enabled>>
_CONSTEXPR array_view<ValueTypeOpt, RestDimensions...> operator[](size_type idx) const _CONSTEXPR array_view<ValueTypeOpt, RestDimensions...> operator[](size_type idx) const
{ {
auto ret = Base::operator[](idx); auto ret = Base::operator[](idx);
@ -1936,6 +1940,7 @@ public:
using typename Base::index_type; using typename Base::index_type;
using typename Base::iterator; using typename Base::iterator;
using typename Base::const_iterator; using typename Base::const_iterator;
using typename Base::reference;
// from static array of size N // from static array of size N
template<size_type N> template<size_type N>
@ -1968,26 +1973,26 @@ public:
} }
// convert from bytes // convert from bytes
template <typename OtherValueType, typename Dummy = std::enable_if_t<std::is_same<value_type, const byte>::value>> template <typename OtherValueType>
strided_array_view<OtherValueType, rank> as_strided_array_view() const strided_array_view<typename std::enable_if<std::is_same<value_type, const byte>::value, OtherValueType>::type, rank> as_strided_array_view() const
{ {
static_assert((sizeof(OtherValueType) >= sizeof(value_type)) && (sizeof(OtherValueType) % sizeof(value_type) == 0), "OtherValueType should have a size to contain a multiple of ValueTypes"); static_assert((sizeof(OtherValueType) >= sizeof(value_type)) && (sizeof(OtherValueType) % sizeof(value_type) == 0), "OtherValueType should have a size to contain a multiple of ValueTypes");
auto d = sizeof(OtherValueType) / sizeof(value_type); auto d = sizeof(OtherValueType) / sizeof(value_type);
size_type size = bounds().total_size() / d; size_type size = this->bounds().total_size() / d;
return{ (OtherValueType*)data(), size, bounds_type{ resize_extent(bounds().index_bounds(), d), resize_stride(bounds().strides(), d)} }; return{ (OtherValueType*)this->data(), size, bounds_type{ resize_extent(this->bounds().index_bounds(), d), resize_stride(this->bounds().strides(), d)} };
} }
strided_array_view section(index_type origin, index_type extents) const strided_array_view section(index_type origin, index_type extents) const
{ {
size_type size = bounds().total_size() - bounds().linearize(origin); size_type size = this->bounds().total_size() - this->bounds().linearize(origin);
return { &this->operator[](origin), size, bounds_type {extents, details::make_stride(Base::bounds())}}; return { &this->operator[](origin), size, bounds_type {extents, details::make_stride(Base::bounds())}};
} }
_CONSTEXPR reference operator[](const index_type& idx) const _CONSTEXPR reference operator[](const index_type& idx) const
{ {
return Base::operator[](idx); return Base::operator[](idx);
} }
template <bool Enabled = (rank > 1), typename Dummy = std::enable_if_t<Enabled>> template <bool Enabled = (rank > 1), typename Dummy = std::enable_if_t<Enabled>>
_CONSTEXPR strided_array_view<value_type, rank-1> operator[](size_type idx) const _CONSTEXPR strided_array_view<value_type, rank-1> operator[](size_type idx) const
@ -2048,7 +2053,7 @@ private:
const ArrayView * m_validator; const ArrayView * m_validator;
void validateThis() const void validateThis() const
{ {
fail_fast_assert(m_pdata >= m_validator->m_pdata && m_pdata < m_validator->m_pdata + m_validator->size(), "iterator is out of range of the array"); fail_fast_assert(m_pdata >= m_validator->m_pdata && m_pdata < m_validator->m_pdata + m_validator->size());
} }
contiguous_array_view_iterator (const ArrayView *container, bool isbegin = false) : contiguous_array_view_iterator (const ArrayView *container, bool isbegin = false) :
m_pdata(isbegin ? container->m_pdata : container->m_pdata + container->size()), m_validator(container) { } m_pdata(isbegin ? container->m_pdata : container->m_pdata + container->size()), m_validator(container) { }

View File

@ -27,13 +27,10 @@ namespace Guide
// //
#if defined(SAFER_CPP_TESTING) #if defined(SAFER_CPP_TESTING)
struct fail_fast : public std::exception struct fail_fast : public std::runtime_error
{ {
fail_fast() = default; fail_fast() : std::runtime_error("") {}
explicit fail_fast(char const* const message) : std::runtime_error(message) {}
explicit fail_fast(char const* const message) :
std::exception(message)
{}
}; };
inline void fail_fast_assert(bool cond) { if (!cond) throw fail_fast(); } inline void fail_fast_assert(bool cond) { if (!cond) throw fail_fast(); }

View File

@ -100,7 +100,7 @@ SUITE(array_view_tests)
// out of bounds // out of bounds
CHECK_THROW(av[1][3] = 3, fail_fast); CHECK_THROW(av[1][3] = 3, fail_fast);
CHECK_THROW((av[index<2>{1, 3}] = 3), fail_fast); CHECK_THROW((av[{1, 3}] = 3), fail_fast);
CHECK_THROW(av[10][2], fail_fast); CHECK_THROW(av[10][2], fail_fast);
CHECK_THROW((av[{10,2}]), fail_fast); CHECK_THROW((av[{10,2}]), fail_fast);
@ -621,14 +621,18 @@ SUITE(array_view_tests)
// stride initializer list size should match the rank of the array // stride initializer list size should match the rank of the array
CHECK_THROW((index<1>{ 0,1 }), fail_fast); CHECK_THROW((index<1>{ 0,1 }), fail_fast);
CHECK_THROW((strided_array_view<int, 1>{ arr, {1, {1,1}} }), fail_fast); CHECK_THROW((strided_array_view<int, 1>{ arr, {1, {1,1}} }), fail_fast);
#ifdef _MSC_VER
CHECK_THROW((strided_array_view<int, 1>{ arr, {{1,1 }, {1,1}} }), fail_fast); CHECK_THROW((strided_array_view<int, 1>{ arr, {{1,1 }, {1,1}} }), fail_fast);
#endif
CHECK_THROW((strided_array_view<int, 1>{ av, {1, {1,1}} }), fail_fast); CHECK_THROW((strided_array_view<int, 1>{ av, {1, {1,1}} }), fail_fast);
#ifdef _MSC_VER
CHECK_THROW((strided_array_view<int, 1>{ av, {{1,1 }, {1,1}} }), fail_fast); CHECK_THROW((strided_array_view<int, 1>{ av, {{1,1 }, {1,1}} }), fail_fast);
#endif
CHECK_THROW((strided_array_view<int, 2>{ av.as_array_view(dim<2>(), dim<2>()), {{1}, {1}} }), fail_fast); CHECK_THROW((strided_array_view<int, 2>{ av.as_array_view(dim<2>(), dim<2>()), {{1}, {1}} }), fail_fast);
CHECK_THROW((strided_array_view<int, 2>{ av.as_array_view(dim<2>(), dim<2>()), {{1}, {1,1,1}} }), fail_fast); CHECK_THROW((strided_array_view<int, 2>{ av.as_array_view(dim<2>(), dim<2>()), {{1}, {1,1,1}} }), fail_fast);
#ifdef _MSC_VER
CHECK_THROW((strided_array_view<int, 2>{ av.as_array_view(dim<2>(), dim<2>()), {{1,1,1}, {1}} }), fail_fast); CHECK_THROW((strided_array_view<int, 2>{ av.as_array_view(dim<2>(), dim<2>()), {{1,1,1}, {1}} }), fail_fast);
#endif
} }
} }
@ -726,69 +730,27 @@ SUITE(array_view_tests)
TEST(empty_arrays) TEST(empty_arrays)
{ {
#ifdef CONFIRM_COMPILATION_ERRORS #ifdef CONFIRM_COMPILATION_ERRORS
{ {
array_view<int, 1> empty; array_view<int, 1> empty;
strided_array_view<int, 2> empty2; strided_array_view<int, 2> empty2;
strided_array_view<int, 1> empty3{ nullptr,{ 0, 1 } }; strided_array_view<int, 1> empty3{ nullptr,{ 0, 1 } };
} }
#endif #endif
{ array_view<int, 0> empty_av(nullptr);
array_view<int, 0> empty_av(nullptr);
CHECK(empty_av.bounds().index_bounds() == index<1>{ 0 }); CHECK(empty_av.bounds().index_bounds() == index<1>{ 0 });
CHECK_THROW(empty_av[0], fail_fast); CHECK_THROW(empty_av[0], fail_fast);
CHECK_THROW(empty_av.begin()[0], fail_fast);
CHECK_THROW(empty_av.cbegin()[0], fail_fast);
for (auto& v : empty_av) strided_array_view<int, 1> empty_sav{ empty_av, { 0, 1 } };
{
CHECK(false);
}
}
{ CHECK(empty_sav.bounds().index_bounds() == index<1>{ 0 });
array_view<int> empty_av = {}; CHECK_THROW(empty_sav[0], fail_fast);
CHECK(empty_av.bounds().index_bounds() == index<1>{ 0 }); strided_array_view<int, 1> empty_sav2{ nullptr, 0, { 0, 1 } };
CHECK_THROW(empty_av[0], fail_fast);
CHECK_THROW(empty_av.begin()[0], fail_fast);
CHECK_THROW(empty_av.cbegin()[0], fail_fast);
for (auto& v : empty_av) CHECK(empty_sav.bounds().index_bounds() == index<1>{ 0 });
{ CHECK_THROW(empty_sav[0], fail_fast);
CHECK(false);
}
}
{
array_view<int, 0> empty_av(nullptr);
strided_array_view<int, 1> empty_sav{ empty_av, { 0, 1 } };
CHECK(empty_sav.bounds().index_bounds() == index<1>{ 0 });
CHECK_THROW(empty_sav[0], fail_fast);
CHECK_THROW(empty_sav.begin()[0], fail_fast);
CHECK_THROW(empty_sav.cbegin()[0], fail_fast);
for (auto& v : empty_sav)
{
CHECK(false);
}
}
{
strided_array_view<int, 1> empty_sav{ nullptr, 0, { 0, 1 } };
CHECK(empty_sav.bounds().index_bounds() == index<1>{ 0 });
CHECK_THROW(empty_sav[0], fail_fast);
CHECK_THROW(empty_sav.begin()[0], fail_fast);
CHECK_THROW(empty_sav.cbegin()[0], fail_fast);
for (auto& v : empty_sav)
{
CHECK(false);
}
}
} }
TEST(index_constructor) TEST(index_constructor)
@ -803,13 +765,13 @@ SUITE(array_view_tests)
array_view<int, dynamic_range> av(arr, 8); array_view<int, dynamic_range> av(arr, 8);
size_t a[1] = { 0 }; size_t a[1] = { 0 };
index<1> i = index<1>(a); index<1> i = a;
CHECK(av[i] == 4); CHECK(av[i] == 4);
auto av2 = av.as_array_view(dim<4>(), dim<>(2)); auto av2 = av.as_array_view(dim<4>(), dim<>(2));
size_t a2[2] = { 0, 1 }; size_t a2[2] = { 0, 1 };
index<2> i2 = index<2>(a2); index<2> i2 = a2;
CHECK(av2[i2] == 0); CHECK(av2[i2] == 0);
CHECK(av2[0][i] == 4); CHECK(av2[0][i] == 4);
@ -890,7 +852,7 @@ SUITE(array_view_tests)
} }
} }
unsigned int idx = 0; size_t idx = 0;
for (auto num : section) for (auto num : section)
{ {
CHECK(num == av[idx][1]); CHECK(num == av[idx][1]);
@ -1498,114 +1460,114 @@ SUITE(array_view_tests)
TEST(ArrayViewComparison) TEST(ArrayViewComparison)
{ {
{ {
int arr[10][2]; int arr[10][2];
auto av1 = as_array_view(arr); auto av1 = as_array_view(arr);
array_view<const int, dynamic_range, 2> av2 = av1; array_view<const int, dynamic_range, 2> av2 = av1;
CHECK(av1 == av2); CHECK(av1 == av2);
array_view<array_view_options<int, char>, 20> av3 = av1.as_array_view(dim<>(20)); array_view<array_view_options<int, char>, 20> av3 = av1.as_array_view(dim<>(20));
CHECK(av3 == av2 && av3 == av1); CHECK(av3 == av2 && av3 == av1);
} }
{ {
auto av1 = nullptr; auto av1 = nullptr;
auto av2 = nullptr; auto av2 = nullptr;
CHECK(av1 == av2); CHECK(av1 == av2);
CHECK(!(av1 != av2)); CHECK(!(av1 != av2));
CHECK(!(av1 < av2)); CHECK(!(av1 < av2));
CHECK(av1 <= av2); CHECK(av1 <= av2);
CHECK(!(av1 > av2)); CHECK(!(av1 > av2));
CHECK(av1 >= av2); CHECK(av1 >= av2);
CHECK(av2 == av1); CHECK(av2 == av1);
CHECK(!(av2 != av1)); CHECK(!(av2 != av1));
CHECK(!(av2 < av1)); CHECK(!(av2 < av1));
CHECK(av2 <= av1); CHECK(av2 <= av1);
CHECK(!(av2 > av1)); CHECK(!(av2 > av1));
CHECK(av2 >= av1); CHECK(av2 >= av1);
} }
{ {
int arr[] = { 2, 1 }; // bigger int arr[] = { 2, 1 }; // bigger
array_view<int> av1 = nullptr; array_view<int> av1 = nullptr;
array_view<int> av2 = arr; array_view<int> av2 = arr;
CHECK(av1 != av2); CHECK(av1 != av2);
CHECK(av2 != av1); CHECK(av2 != av1);
CHECK(!(av1 == av2)); CHECK(!(av1 == av2));
CHECK(!(av2 == av1)); CHECK(!(av2 == av1));
CHECK(av1 < av2); CHECK(av1 < av2);
CHECK(!(av2 < av1)); CHECK(!(av2 < av1));
CHECK(av1 <= av2); CHECK(av1 <= av2);
CHECK(!(av2 <= av1)); CHECK(!(av2 <= av1));
CHECK(av2 > av1); CHECK(av2 > av1);
CHECK(!(av1 > av2)); CHECK(!(av1 > av2));
CHECK(av2 >= av1); CHECK(av2 >= av1);
CHECK(!(av1 >= av2)); CHECK(!(av1 >= av2));
} }
{ {
int arr1[] = { 1, 2 }; int arr1[] = { 1, 2 };
int arr2[] = { 1, 2 }; int arr2[] = { 1, 2 };
array_view<int> av1 = arr1; array_view<int> av1 = arr1;
array_view<int> av2 = arr2; array_view<int> av2 = arr2;
CHECK(av1 == av2); CHECK(av1 == av2);
CHECK(!(av1 != av2)); CHECK(!(av1 != av2));
CHECK(!(av1 < av2)); CHECK(!(av1 < av2));
CHECK(av1 <= av2); CHECK(av1 <= av2);
CHECK(!(av1 > av2)); CHECK(!(av1 > av2));
CHECK(av1 >= av2); CHECK(av1 >= av2);
CHECK(av2 == av1); CHECK(av2 == av1);
CHECK(!(av2 != av1)); CHECK(!(av2 != av1));
CHECK(!(av2 < av1)); CHECK(!(av2 < av1));
CHECK(av2 <= av1); CHECK(av2 <= av1);
CHECK(!(av2 > av1)); CHECK(!(av2 > av1));
CHECK(av2 >= av1); CHECK(av2 >= av1);
} }
{ {
int arr[] = { 1, 2, 3 }; int arr[] = { 1, 2, 3 };
array_view<int> av1 = { &arr[0], 2 }; // shorter array_view<int> av1 = { &arr[0], 2 }; // shorter
array_view<int> av2 = arr; // longer array_view<int> av2 = arr; // longer
CHECK(av1 != av2); CHECK(av1 != av2);
CHECK(av2 != av1); CHECK(av2 != av1);
CHECK(!(av1 == av2)); CHECK(!(av1 == av2));
CHECK(!(av2 == av1)); CHECK(!(av2 == av1));
CHECK(av1 < av2); CHECK(av1 < av2);
CHECK(!(av2 < av1)); CHECK(!(av2 < av1));
CHECK(av1 <= av2); CHECK(av1 <= av2);
CHECK(!(av2 <= av1)); CHECK(!(av2 <= av1));
CHECK(av2 > av1); CHECK(av2 > av1);
CHECK(!(av1 > av2)); CHECK(!(av1 > av2));
CHECK(av2 >= av1); CHECK(av2 >= av1);
CHECK(!(av1 >= av2)); CHECK(!(av1 >= av2));
} }
{ {
int arr1[] = { 1, 2 }; // smaller int arr1[] = { 1, 2 }; // smaller
int arr2[] = { 2, 1 }; // bigger int arr2[] = { 2, 1 }; // bigger
array_view<int> av1 = arr1; array_view<int> av1 = arr1;
array_view<int> av2 = arr2; array_view<int> av2 = arr2;
CHECK(av1 != av2); CHECK(av1 != av2);
CHECK(av2 != av1); CHECK(av2 != av1);
CHECK(!(av1 == av2)); CHECK(!(av1 == av2));
CHECK(!(av2 == av1)); CHECK(!(av2 == av1));
CHECK(av1 < av2); CHECK(av1 < av2);
CHECK(!(av2 < av1)); CHECK(!(av2 < av1));
CHECK(av1 <= av2); CHECK(av1 <= av2);
CHECK(!(av2 <= av1)); CHECK(!(av2 <= av1));
CHECK(av2 > av1); CHECK(av2 > av1);
CHECK(!(av1 > av2)); CHECK(!(av1 > av2));
CHECK(av2 >= av1); CHECK(av2 >= av1);
CHECK(!(av1 >= av2)); CHECK(!(av1 >= av2));
} }
} }
} }