mirror of
https://github.com/microsoft/GSL.git
synced 2024-11-03 17:56:43 -05:00
Checking in to continue working elsewhere.
This commit is contained in:
parent
cc22f2bf42
commit
502cd6650a
@ -94,20 +94,22 @@ public:
|
||||
constexpr static const index_type extent = Extent;
|
||||
|
||||
// [span.cons], span constructors, copy, assignment, and destructor
|
||||
constexpr span() noexcept : data_(nullptr), size_(0)
|
||||
{ static_assert(extent == dynamic_extent || extent == 0, "Cannot default initialize a fixed-length span."); }
|
||||
constexpr span() noexcept : storage_(nullptr, extent_type<0>())
|
||||
{}
|
||||
|
||||
constexpr span(nullptr_t) noexcept : span()
|
||||
{}
|
||||
|
||||
constexpr span(pointer ptr, index_type count) : data_(ptr), size_(count)
|
||||
{ Expects(((!ptr && count == 0) || (ptr && count >= 0)) && (extent == dynamic_extent || extent == count)); }
|
||||
constexpr span(pointer ptr, index_type count) : storage_(ptr, count)
|
||||
{ Expects(((!ptr && count == 0) || (ptr && count >= 0))); }
|
||||
|
||||
constexpr span(pointer firstElem, pointer lastElem) : data_(firstElem), size_(std::distance(firstElem, lastElem))
|
||||
{ Expects(size_ >= 0 && (extent == dynamic_extent || extent == size_)); }
|
||||
constexpr span(pointer firstElem, pointer lastElem)
|
||||
: storage_(firstElem, std::distance(firstElem, lastElem))
|
||||
{}
|
||||
|
||||
template <size_t N>
|
||||
constexpr span(element_type(&arr)[N]) {}
|
||||
constexpr span(element_type(&arr)[N]) : storage_(&arr[0], extent_type<N>())
|
||||
{}
|
||||
|
||||
#if 0 // TODO
|
||||
template <size_t N>
|
||||
@ -141,7 +143,7 @@ public:
|
||||
#endif
|
||||
// [span.obs], span observers
|
||||
constexpr index_type length() const noexcept { return size(); }
|
||||
constexpr index_type size() const noexcept { return size_; }
|
||||
constexpr index_type size() const noexcept { return storage_.size(); }
|
||||
constexpr index_type length_bytes() const noexcept { return size_bytes(); }
|
||||
constexpr index_type size_bytes() const noexcept { return size() * sizeof(element_type); }
|
||||
constexpr bool empty() const noexcept { return size() == 0; }
|
||||
@ -149,11 +151,11 @@ public:
|
||||
// [span.elem], span element access
|
||||
constexpr reference operator[](index_type idx) const
|
||||
{
|
||||
Expects(idx >= 0 && idx < size_);
|
||||
return data_[idx];
|
||||
Expects(idx >= 0 && idx < storage_.size());
|
||||
return storage_.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 storage_.data(); }
|
||||
#if 0 // TODO
|
||||
// [span.iter], span iterator support
|
||||
iterator begin() const noexcept;
|
||||
@ -169,8 +171,70 @@ public:
|
||||
const_reverse_iterator crend() const noexcept;
|
||||
#endif
|
||||
private:
|
||||
pointer data_;
|
||||
template <index_type Extent>
|
||||
class extent_type;
|
||||
|
||||
template <index_type Extent>
|
||||
class extent_type
|
||||
{
|
||||
public:
|
||||
static_assert(Extent >= 0, "A fixed-size span must be >= 0 in size.");
|
||||
|
||||
constexpr extent_type() noexcept {}
|
||||
|
||||
template <index_type Other>
|
||||
constexpr extent_type(extent_type<Other>) noexcept
|
||||
{
|
||||
static_assert(Other == Extent,
|
||||
"Mismatch between fixed-size extent and size of initializing data.");
|
||||
}
|
||||
|
||||
constexpr extent_type(index_type size)
|
||||
{ Expects(size == Extent); }
|
||||
|
||||
constexpr inline index_type size() const noexcept { return Extent; }
|
||||
};
|
||||
|
||||
template <>
|
||||
class extent_type<dynamic_extent>
|
||||
{
|
||||
public:
|
||||
template <index_type Other>
|
||||
explicit constexpr extent_type(extent_type<Other> ext) : size_(ext.size())
|
||||
{}
|
||||
|
||||
explicit constexpr extent_type(index_type size) : size_(size)
|
||||
{ Expects(size >= 0); }
|
||||
|
||||
constexpr inline index_type size() const noexcept
|
||||
{ return size_; }
|
||||
|
||||
private:
|
||||
index_type size_;
|
||||
};
|
||||
|
||||
// this implementation detail class lets us take advantage of the
|
||||
// empty base class optimization to pay for only storage of a single
|
||||
// pointer in the case of fixed-size spans
|
||||
template <class ExtentType>
|
||||
class storage_type : public ExtentType
|
||||
{
|
||||
public:
|
||||
template <class OtherExtentType>
|
||||
storage_type(pointer data, OtherExtentType ext)
|
||||
: ExtentType(ext), data_(data) {}
|
||||
|
||||
//storage_type(pointer data, ExtentType ext)
|
||||
// : ExtentType(ext), data_(data) {}
|
||||
|
||||
constexpr inline pointer data() const noexcept
|
||||
{ return data_; }
|
||||
|
||||
private:
|
||||
pointer data_;
|
||||
};
|
||||
|
||||
storage_type<extent_type<Extent>> storage_;
|
||||
};
|
||||
|
||||
|
||||
|
@ -73,6 +73,19 @@ SUITE(span_tests)
|
||||
}
|
||||
}
|
||||
|
||||
TEST(size_optimization)
|
||||
{
|
||||
{
|
||||
span<int> s;
|
||||
CHECK(sizeof(s) == sizeof(int*) + sizeof(ptrdiff_t));
|
||||
}
|
||||
|
||||
{
|
||||
span<int, 0> s;
|
||||
CHECK(sizeof(s) == sizeof(int*));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(from_nullptr_constructor)
|
||||
{
|
||||
{
|
||||
@ -250,7 +263,7 @@ SUITE(span_tests)
|
||||
// CHECK_THROW(workaround_macro(), fail_fast);
|
||||
//}
|
||||
}
|
||||
#if 0
|
||||
|
||||
TEST(from_array_constructor)
|
||||
{
|
||||
int arr[5] = {1, 2, 3, 4, 5};
|
||||
@ -265,10 +278,11 @@ SUITE(span_tests)
|
||||
CHECK(s.length() == 5 && s.data() == &arr[0]);
|
||||
}
|
||||
|
||||
{
|
||||
int arr2d[2][3] = { 1, 2, 3, 4, 5, 6 };
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
{
|
||||
span<int, 6> s{arr};
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
@ -276,8 +290,6 @@ SUITE(span_tests)
|
||||
CHECK(s.length() == 0 && s.data() == &arr[0]);
|
||||
}
|
||||
|
||||
int arr2d[2][3] = {1, 2, 3, 4, 5, 6};
|
||||
|
||||
{
|
||||
span<int> s{arr2d};
|
||||
CHECK(s.length() == 6 && s.data() == &arr2d[0][0]);
|
||||
@ -290,43 +302,17 @@ SUITE(span_tests)
|
||||
}
|
||||
|
||||
{
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
span<int, 5> s{arr2d};
|
||||
span<int, 6> s{ arr2d };
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
span<int, 6> s{arr2d};
|
||||
CHECK(s.length() == 6 && s.data() == &arr2d[0][0]);
|
||||
CHECK(s[0] == 1 && s[5] == 6);
|
||||
}
|
||||
|
||||
{
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
span<int, 7> s{arr2d};
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
span<int[3]> s{arr2d[0]};
|
||||
span<int[3]> s{ arr2d[0] };
|
||||
CHECK(s.length() == 1 && s.data() == &arr2d[0]);
|
||||
}
|
||||
|
||||
{
|
||||
span<int, 2, 3> s{arr2d};
|
||||
CHECK(s.length() == 6 && s.data() == &arr2d[0][0]);
|
||||
auto workaround_macro = [&]() { return s[{1, 2}] == 6; };
|
||||
CHECK(workaround_macro());
|
||||
}
|
||||
|
||||
{
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
span<int, 3, 3> s{arr2d};
|
||||
#endif
|
||||
}
|
||||
|
||||
int arr3d[2][3][2] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
{
|
||||
span<int> s{arr3d};
|
||||
CHECK(s.length() == 12 && s.data() == &arr3d[0][0][0]);
|
||||
@ -339,9 +325,7 @@ SUITE(span_tests)
|
||||
}
|
||||
|
||||
{
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
span<int, 11> s{arr3d};
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
@ -349,32 +333,13 @@ SUITE(span_tests)
|
||||
CHECK(s.length() == 12 && s.data() == &arr3d[0][0][0]);
|
||||
CHECK(s[0] == 1 && s[5] == 6);
|
||||
}
|
||||
|
||||
{
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
span<int, 13> s{arr3d};
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
span<int[3][2]> s{arr3d[0]};
|
||||
CHECK(s.length() == 1 && s.data() == &arr3d[0]);
|
||||
}
|
||||
|
||||
{
|
||||
span<int, 3, 2, 2> s{arr3d};
|
||||
CHECK(s.length() == 12 && s.data() == &arr3d[0][0][0]);
|
||||
auto workaround_macro = [&]() { return s[{2, 1, 0}] == 11; };
|
||||
CHECK(workaround_macro());
|
||||
}
|
||||
|
||||
{
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
span<int, 3, 3, 3> s{arr3d};
|
||||
#endif
|
||||
//span<int[3][2]> s{arr3d[0]};
|
||||
//CHECK(s.length() == 1 && s.data() == &arr3d[0]);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
TEST(from_dynamic_array_constructor)
|
||||
{
|
||||
double(*arr)[3][4] = new double[100][3][4];
|
||||
|
Loading…
Reference in New Issue
Block a user