first/last constructor working.

This commit is contained in:
Neil MacIntosh 2016-02-25 11:42:26 -08:00
parent d3929c59a0
commit cc22f2bf42
2 changed files with 45 additions and 80 deletions

View File

@ -96,13 +96,20 @@ public:
// [span.cons], span constructors, copy, assignment, and destructor // [span.cons], span constructors, copy, assignment, and destructor
constexpr span() noexcept : data_(nullptr), size_(0) constexpr span() noexcept : data_(nullptr), size_(0)
{ static_assert(extent == dynamic_extent || extent == 0, "Cannot default initialize a fixed-length span."); } { static_assert(extent == dynamic_extent || extent == 0, "Cannot default initialize a fixed-length span."); }
constexpr span(nullptr_t) noexcept : span() {}
constexpr span(nullptr_t) noexcept : span()
{}
constexpr span(pointer ptr, index_type count) : data_(ptr), size_(count) constexpr span(pointer ptr, index_type count) : data_(ptr), size_(count)
{ Expects((!ptr && count == 0) || (ptr && count >= 0)); } { Expects(((!ptr && count == 0) || (ptr && count >= 0)) && (extent == dynamic_extent || extent == count)); }
#if 0 // TODO
constexpr span(pointer firstElem, pointer lastElem); constexpr span(pointer firstElem, pointer lastElem) : data_(firstElem), size_(std::distance(firstElem, lastElem))
{ Expects(size_ >= 0 && (extent == dynamic_extent || extent == size_)); }
template <size_t N> template <size_t N>
constexpr span(element_type(&arr)[N]); constexpr span(element_type(&arr)[N]) {}
#if 0 // TODO
template <size_t N> template <size_t N>
constexpr span(array<remove_const_t<element_type>, N>& arr); constexpr span(array<remove_const_t<element_type>, N>& arr);
template <size_t N> template <size_t N>
@ -139,11 +146,13 @@ public:
constexpr index_type size_bytes() const noexcept { return size() * sizeof(element_type); } constexpr index_type size_bytes() const noexcept { return size() * sizeof(element_type); }
constexpr bool empty() const noexcept { return size() == 0; } constexpr bool empty() const noexcept { return size() == 0; }
#if 0 // TODO
// [span.elem], span element access // [span.elem], span element access
constexpr reference operator[](index_type idx) const; constexpr reference operator[](index_type idx) const
constexpr reference operator()(index_type idx) const; {
#endif Expects(idx >= 0 && idx < size_);
return data_[idx];
}
constexpr reference operator()(index_type idx) const { return this->operator[](idx); }
constexpr pointer data() const noexcept { return data_; } constexpr pointer data() const noexcept { return data_; }
#if 0 // TODO #if 0 // TODO
// [span.iter], span iterator support // [span.iter], span iterator support

View File

@ -115,7 +115,6 @@ SUITE(span_tests)
} }
} }
#if 0
TEST(from_nullptr_length_constructor) TEST(from_nullptr_length_constructor)
{ {
{ {
@ -135,10 +134,8 @@ SUITE(span_tests)
} }
{ {
#ifdef CONFIRM_COMPILATION_ERRORS auto workaround_macro = []() { span<int, 1> s{ nullptr, 0 }; };
span<int, 1> s{nullptr, 0}; CHECK_THROW(workaround_macro(), fail_fast);
CHECK(s.length() == 1 && s.data() == nullptr); // explains why it can't compile
#endif
} }
{ {
@ -166,56 +163,6 @@ SUITE(span_tests)
} }
} }
TEST(from_element_constructor)
{
int i = 5;
{
span<int> s = i;
CHECK(s.length() == 1 && s.data() == &i);
CHECK(s[0] == 5);
span<const int> cs = i;
CHECK(cs.length() == 1 && cs.data() == &i);
CHECK(cs[0] == 5);
}
{
#ifdef CONFIRM_COMPILATION_ERRORS
const j = 1;
span<int, 0> s = j;
#endif
}
{
#ifdef CONFIRM_COMPILATION_ERRORS
span<int, 0> s = i;
CHECK(s.length() == 0 && s.data() == &i);
#endif
}
{
span<int, 1> s = i;
CHECK(s.length() == 1 && s.data() == &i);
CHECK(s[0] == 5);
}
{
#ifdef CONFIRM_COMPILATION_ERRORS
span<int, 2> s = i;
CHECK(s.length() == 2 && s.data() == &i);
#endif
}
{
#ifdef CONFIRM_COMPILATION_ERRORS
auto get_a_temp = []() -> int { return 4; };
auto use_a_span = [](span<int> s) { (void) s; };
use_a_span(get_a_temp());
#endif
}
}
TEST(from_pointer_length_constructor) TEST(from_pointer_length_constructor)
{ {
int arr[4] = {1, 2, 3, 4}; int arr[4] = {1, 2, 3, 4};
@ -271,30 +218,39 @@ SUITE(span_tests)
CHECK(s.length() == 0 && s.data() == &arr[0]); CHECK(s.length() == 0 && s.data() == &arr[0]);
} }
// this will fail the std::distance() precondition, which asserts on MSVC debug builds
//{
// auto workaround_macro = [&]() { span<int> s{&arr[1], &arr[0]}; };
// CHECK_THROW(workaround_macro(), fail_fast);
//}
// this will fail the std::distance() precondition, which asserts on MSVC debug builds
//{
// int* p = nullptr;
// auto workaround_macro = [&]() { span<int> s{&arr[0], p}; };
// CHECK_THROW(workaround_macro(), fail_fast);
//}
{ {
auto workaround_macro = [&]() { span<int> s{&arr[1], &arr[0]}; }; int* p = nullptr;
CHECK_THROW(workaround_macro(), fail_fast); span<int> s{ p, p };
CHECK(s.length() == 0 && s.data() == nullptr);
} }
{ {
int* p = nullptr; int* p = nullptr;
auto workaround_macro = [&]() { span<int> s{&arr[0], p}; }; span<int, 0> s{ p, p };
CHECK_THROW(workaround_macro(), fail_fast); CHECK(s.length() == 0 && s.data() == nullptr);
} }
{ // this will fail the std::distance() precondition, which asserts on MSVC debug builds
int* p = nullptr; //{
auto workaround_macro = [&]() { span<int> s{p, p}; }; // int* p = nullptr;
CHECK_THROW(workaround_macro(), fail_fast); // auto workaround_macro = [&]() { span<int> s{&arr[0], p}; };
// CHECK_THROW(workaround_macro(), fail_fast);
//}
} }
#if 0
{
int* p = nullptr;
auto workaround_macro = [&]() { span<int> s{&arr[0], p}; };
CHECK_THROW(workaround_macro(), fail_fast);
}
}
TEST(from_array_constructor) TEST(from_array_constructor)
{ {
int arr[5] = {1, 2, 3, 4, 5}; int arr[5] = {1, 2, 3, 4, 5};