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;
|
constexpr static const index_type extent = Extent;
|
||||||
|
|
||||||
// [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 : storage_(nullptr, extent_type<0>())
|
||||||
{ 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) : storage_(ptr, count)
|
||||||
{ Expects(((!ptr && count == 0) || (ptr && count >= 0)) && (extent == dynamic_extent || extent == count)); }
|
{ Expects(((!ptr && count == 0) || (ptr && count >= 0))); }
|
||||||
|
|
||||||
constexpr span(pointer firstElem, pointer lastElem) : data_(firstElem), size_(std::distance(firstElem, lastElem))
|
constexpr span(pointer firstElem, pointer lastElem)
|
||||||
{ Expects(size_ >= 0 && (extent == dynamic_extent || extent == size_)); }
|
: storage_(firstElem, std::distance(firstElem, lastElem))
|
||||||
|
{}
|
||||||
|
|
||||||
template <size_t N>
|
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
|
#if 0 // TODO
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
@ -141,7 +143,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
// [span.obs], span observers
|
// [span.obs], span observers
|
||||||
constexpr index_type length() const noexcept { return size(); }
|
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 length_bytes() const noexcept { return size_bytes(); }
|
||||||
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; }
|
||||||
@ -149,11 +151,11 @@ public:
|
|||||||
// [span.elem], span element access
|
// [span.elem], span element access
|
||||||
constexpr reference operator[](index_type idx) const
|
constexpr reference operator[](index_type idx) const
|
||||||
{
|
{
|
||||||
Expects(idx >= 0 && idx < size_);
|
Expects(idx >= 0 && idx < storage_.size());
|
||||||
return data_[idx];
|
return storage_.data()[idx];
|
||||||
}
|
}
|
||||||
constexpr reference operator()(index_type idx) const { return this->operator[](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
|
#if 0 // TODO
|
||||||
// [span.iter], span iterator support
|
// [span.iter], span iterator support
|
||||||
iterator begin() const noexcept;
|
iterator begin() const noexcept;
|
||||||
@ -169,8 +171,70 @@ public:
|
|||||||
const_reverse_iterator crend() const noexcept;
|
const_reverse_iterator crend() const noexcept;
|
||||||
#endif
|
#endif
|
||||||
private:
|
private:
|
||||||
pointer data_;
|
template <index_type Extent>
|
||||||
index_type size_;
|
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)
|
TEST(from_nullptr_constructor)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
@ -250,7 +263,7 @@ SUITE(span_tests)
|
|||||||
// CHECK_THROW(workaround_macro(), fail_fast);
|
// CHECK_THROW(workaround_macro(), fail_fast);
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
TEST(from_array_constructor)
|
TEST(from_array_constructor)
|
||||||
{
|
{
|
||||||
int arr[5] = {1, 2, 3, 4, 5};
|
int arr[5] = {1, 2, 3, 4, 5};
|
||||||
@ -265,10 +278,11 @@ SUITE(span_tests)
|
|||||||
CHECK(s.length() == 5 && s.data() == &arr[0]);
|
CHECK(s.length() == 5 && s.data() == &arr[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
int arr2d[2][3] = { 1, 2, 3, 4, 5, 6 };
|
||||||
|
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
|
{
|
||||||
span<int, 6> s{arr};
|
span<int, 6> s{arr};
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -276,8 +290,6 @@ SUITE(span_tests)
|
|||||||
CHECK(s.length() == 0 && s.data() == &arr[0]);
|
CHECK(s.length() == 0 && s.data() == &arr[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int arr2d[2][3] = {1, 2, 3, 4, 5, 6};
|
|
||||||
|
|
||||||
{
|
{
|
||||||
span<int> s{arr2d};
|
span<int> s{arr2d};
|
||||||
CHECK(s.length() == 6 && s.data() == &arr2d[0][0]);
|
CHECK(s.length() == 6 && s.data() == &arr2d[0][0]);
|
||||||
@ -290,43 +302,17 @@ SUITE(span_tests)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
span<int, 6> s{ arr2d };
|
||||||
span<int, 5> s{arr2d};
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
span<int, 6> s{arr2d};
|
span<int[3]> s{ arr2d[0] };
|
||||||
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]};
|
|
||||||
CHECK(s.length() == 1 && s.data() == &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};
|
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};
|
span<int> s{arr3d};
|
||||||
CHECK(s.length() == 12 && s.data() == &arr3d[0][0][0]);
|
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};
|
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.length() == 12 && s.data() == &arr3d[0][0][0]);
|
||||||
CHECK(s[0] == 1 && s[5] == 6);
|
CHECK(s[0] == 1 && s[5] == 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
|
||||||
span<int, 13> s{arr3d};
|
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
span<int[3][2]> s{arr3d[0]};
|
//span<int[3][2]> s{arr3d[0]};
|
||||||
CHECK(s.length() == 1 && s.data() == &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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
TEST(from_dynamic_array_constructor)
|
TEST(from_dynamic_array_constructor)
|
||||||
{
|
{
|
||||||
double(*arr)[3][4] = new double[100][3][4];
|
double(*arr)[3][4] = new double[100][3][4];
|
||||||
|
Loading…
Reference in New Issue
Block a user