mirror of
https://github.com/microsoft/GSL.git
synced 2024-11-03 17:56:43 -05:00
Merge branch 'master' into clang-cl_2
This commit is contained in:
commit
9f3492064b
@ -315,33 +315,33 @@ namespace details
|
|||||||
|
|
||||||
// TODO : following signature is for work around VS bug
|
// TODO : following signature is for work around VS bug
|
||||||
template <typename OtherRange>
|
template <typename OtherRange>
|
||||||
BoundsRanges(const OtherRange&, bool /* firstLevel */)
|
constexpr BoundsRanges(const OtherRange&, bool /* firstLevel */)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
BoundsRanges(const std::ptrdiff_t* const) {}
|
constexpr BoundsRanges(const std::ptrdiff_t* const) {}
|
||||||
BoundsRanges() noexcept = default;
|
constexpr BoundsRanges() noexcept = default;
|
||||||
|
|
||||||
template <typename T, std::size_t Dim>
|
template <typename T, std::size_t Dim>
|
||||||
void serialize(T&) const
|
constexpr void serialize(T&) const
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <typename T, std::size_t Dim>
|
template <typename T, std::size_t Dim>
|
||||||
size_type linearize(const T&) const
|
constexpr size_type linearize(const T&) const
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, std::size_t Dim>
|
template <typename T, std::size_t Dim>
|
||||||
size_type contains(const T&) const
|
constexpr size_type contains(const T&) const
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_type elementNum(std::size_t) const noexcept { return 0; }
|
constexpr size_type elementNum(std::size_t) const noexcept { return 0; }
|
||||||
|
|
||||||
size_type totalSize() const noexcept { return TotalSize; }
|
constexpr size_type totalSize() const noexcept { return TotalSize; }
|
||||||
|
|
||||||
bool operator==(const BoundsRanges&) const noexcept { return true; }
|
constexpr bool operator==(const BoundsRanges&) const noexcept { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <std::ptrdiff_t... RestRanges>
|
template <std::ptrdiff_t... RestRanges>
|
||||||
@ -360,23 +360,23 @@ namespace details
|
|||||||
public:
|
public:
|
||||||
GSL_SUPPRESS(f.23) // NO-FORMAT: attribute // this pointer type is cannot be assigned nullptr - issue in not_null
|
GSL_SUPPRESS(f.23) // NO-FORMAT: attribute // this pointer type is cannot be assigned nullptr - issue in not_null
|
||||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||||
BoundsRanges(const std::ptrdiff_t* const arr)
|
constexpr BoundsRanges(const std::ptrdiff_t* const arr)
|
||||||
: Base(arr + 1), m_bound(*arr * this->Base::totalSize())
|
: Base(arr + 1), m_bound(*arr * this->Base::totalSize())
|
||||||
{
|
{
|
||||||
Expects(0 <= *arr);
|
Expects(0 <= *arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
BoundsRanges() noexcept : m_bound(0) {}
|
constexpr BoundsRanges() noexcept : m_bound(0) {}
|
||||||
|
|
||||||
template <std::ptrdiff_t OtherRange, std::ptrdiff_t... RestOtherRanges>
|
template <std::ptrdiff_t OtherRange, std::ptrdiff_t... RestOtherRanges>
|
||||||
BoundsRanges(const BoundsRanges<OtherRange, RestOtherRanges...>& other,
|
constexpr BoundsRanges(const BoundsRanges<OtherRange, RestOtherRanges...>& other,
|
||||||
bool /* firstLevel */ = true)
|
bool /* firstLevel */ = true)
|
||||||
: Base(static_cast<const BoundsRanges<RestOtherRanges...>&>(other), false)
|
: Base(static_cast<const BoundsRanges<RestOtherRanges...>&>(other), false)
|
||||||
, m_bound(other.totalSize())
|
, m_bound(other.totalSize())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <typename T, std::size_t Dim = 0>
|
template <typename T, std::size_t Dim = 0>
|
||||||
void serialize(T& arr) const
|
constexpr void serialize(T& arr) const
|
||||||
{
|
{
|
||||||
arr[Dim] = elementNum();
|
arr[Dim] = elementNum();
|
||||||
this->Base::template serialize<T, Dim + 1>(arr);
|
this->Base::template serialize<T, Dim + 1>(arr);
|
||||||
@ -384,7 +384,7 @@ namespace details
|
|||||||
|
|
||||||
template <typename T, std::size_t Dim = 0>
|
template <typename T, std::size_t Dim = 0>
|
||||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||||
size_type linearize(const T& arr) const
|
constexpr size_type linearize(const T& arr) const
|
||||||
{
|
{
|
||||||
const size_type index = this->Base::totalSize() * arr[Dim];
|
const size_type index = this->Base::totalSize() * arr[Dim];
|
||||||
Expects(index < m_bound);
|
Expects(index < m_bound);
|
||||||
@ -392,7 +392,7 @@ namespace details
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, std::size_t Dim = 0>
|
template <typename T, std::size_t Dim = 0>
|
||||||
size_type contains(const T& arr) const
|
constexpr size_type contains(const T& arr) const
|
||||||
{
|
{
|
||||||
const ptrdiff_t last = this->Base::template contains<T, Dim + 1>(arr);
|
const ptrdiff_t last = this->Base::template contains<T, Dim + 1>(arr);
|
||||||
if (last == -1) return -1;
|
if (last == -1) return -1;
|
||||||
@ -401,18 +401,18 @@ namespace details
|
|||||||
}
|
}
|
||||||
|
|
||||||
GSL_SUPPRESS(c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used
|
GSL_SUPPRESS(c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used
|
||||||
size_type totalSize() const noexcept
|
constexpr size_type totalSize() const noexcept
|
||||||
{
|
{
|
||||||
return m_bound;
|
return m_bound;
|
||||||
}
|
}
|
||||||
|
|
||||||
GSL_SUPPRESS(c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used
|
GSL_SUPPRESS(c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used
|
||||||
size_type elementNum() const noexcept
|
constexpr size_type elementNum() const noexcept
|
||||||
{
|
{
|
||||||
return totalSize() / this->Base::totalSize();
|
return totalSize() / this->Base::totalSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_type elementNum(std::size_t dim) const noexcept
|
constexpr size_type elementNum(std::size_t dim) const noexcept
|
||||||
{
|
{
|
||||||
if (dim > 0)
|
if (dim > 0)
|
||||||
return this->Base::elementNum(dim - 1);
|
return this->Base::elementNum(dim - 1);
|
||||||
@ -420,7 +420,7 @@ namespace details
|
|||||||
return elementNum();
|
return elementNum();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const BoundsRanges& rhs) const noexcept
|
constexpr bool operator==(const BoundsRanges& rhs) const noexcept
|
||||||
{
|
{
|
||||||
return m_bound == rhs.m_bound &&
|
return m_bound == rhs.m_bound &&
|
||||||
static_cast<const Base&>(*this) == static_cast<const Base&>(rhs);
|
static_cast<const Base&>(*this) == static_cast<const Base&>(rhs);
|
||||||
@ -438,11 +438,11 @@ namespace details
|
|||||||
static const size_type TotalSize =
|
static const size_type TotalSize =
|
||||||
Base::TotalSize == dynamic_range ? dynamic_range : CurrentRange * Base::TotalSize;
|
Base::TotalSize == dynamic_range ? dynamic_range : CurrentRange * Base::TotalSize;
|
||||||
|
|
||||||
BoundsRanges(const std::ptrdiff_t* const arr) : Base(arr) {}
|
constexpr BoundsRanges(const std::ptrdiff_t* const arr) : Base(arr) {}
|
||||||
BoundsRanges() = default;
|
constexpr BoundsRanges() = default;
|
||||||
|
|
||||||
template <std::ptrdiff_t OtherRange, std::ptrdiff_t... RestOtherRanges>
|
template <std::ptrdiff_t OtherRange, std::ptrdiff_t... RestOtherRanges>
|
||||||
BoundsRanges(const BoundsRanges<OtherRange, RestOtherRanges...>& other,
|
constexpr BoundsRanges(const BoundsRanges<OtherRange, RestOtherRanges...>& other,
|
||||||
bool firstLevel = true)
|
bool firstLevel = true)
|
||||||
: Base(static_cast<const BoundsRanges<RestOtherRanges...>&>(other), false)
|
: Base(static_cast<const BoundsRanges<RestOtherRanges...>&>(other), false)
|
||||||
{
|
{
|
||||||
@ -451,25 +451,25 @@ namespace details
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, std::size_t Dim = 0>
|
template <typename T, std::size_t Dim = 0>
|
||||||
void serialize(T& arr) const
|
constexpr void serialize(T& arr) const
|
||||||
{
|
{
|
||||||
arr[Dim] = elementNum();
|
arr[Dim] = elementNum();
|
||||||
this->Base::template serialize<T, Dim + 1>(arr);
|
this->Base::template serialize<T, Dim + 1>(arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, std::size_t Dim = 0>
|
template <typename T, std::size_t Dim = 0>
|
||||||
size_type linearize(const T& arr) const
|
constexpr size_type linearize(const T& arr) const
|
||||||
{
|
{
|
||||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||||
Expects(arr[Dim] >= 0 && arr[Dim] < CurrentRange); // Index is out of range
|
Expects(arr[Dim] >= 0 && arr[Dim] < CurrentRange); // Index is out of range
|
||||||
|
|
||||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||||
return this->Base::totalSize() * arr[Dim] +
|
const ptrdiff_t d = arr[Dim];
|
||||||
|
return this->Base::totalSize() * d +
|
||||||
this->Base::template linearize<T, Dim + 1>(arr);
|
this->Base::template linearize<T, Dim + 1>(arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, std::size_t Dim = 0>
|
template <typename T, std::size_t Dim = 0>
|
||||||
size_type contains(const T& arr) const
|
constexpr size_type contains(const T& arr) const
|
||||||
{
|
{
|
||||||
if (arr[Dim] >= CurrentRange) return -1;
|
if (arr[Dim] >= CurrentRange) return -1;
|
||||||
const size_type last = this->Base::template contains<T, Dim + 1>(arr);
|
const size_type last = this->Base::template contains<T, Dim + 1>(arr);
|
||||||
@ -478,19 +478,19 @@ namespace details
|
|||||||
}
|
}
|
||||||
|
|
||||||
GSL_SUPPRESS(c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used
|
GSL_SUPPRESS(c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used
|
||||||
size_type totalSize() const noexcept
|
constexpr size_type totalSize() const noexcept
|
||||||
{
|
{
|
||||||
return CurrentRange * this->Base::totalSize();
|
return CurrentRange * this->Base::totalSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
GSL_SUPPRESS(c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used
|
GSL_SUPPRESS(c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used
|
||||||
size_type elementNum() const noexcept
|
constexpr size_type elementNum() const noexcept
|
||||||
{
|
{
|
||||||
return CurrentRange;
|
return CurrentRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
GSL_SUPPRESS(c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used
|
GSL_SUPPRESS(c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used
|
||||||
size_type elementNum(std::size_t dim) const noexcept
|
constexpr size_type elementNum(std::size_t dim) const noexcept
|
||||||
{
|
{
|
||||||
if (dim > 0)
|
if (dim > 0)
|
||||||
return this->Base::elementNum(dim - 1);
|
return this->Base::elementNum(dim - 1);
|
||||||
@ -498,7 +498,7 @@ namespace details
|
|||||||
return elementNum();
|
return elementNum();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const BoundsRanges& rhs) const noexcept
|
constexpr bool operator==(const BoundsRanges& rhs) const noexcept
|
||||||
{
|
{
|
||||||
return static_cast<const Base&>(*this) == static_cast<const Base&>(rhs);
|
return static_cast<const Base&>(*this) == static_cast<const Base&>(rhs);
|
||||||
}
|
}
|
||||||
|
@ -394,17 +394,27 @@ public:
|
|||||||
: storage_(KnownNotNull{std::addressof(arr[0])}, details::extent_type<N>())
|
: storage_(KnownNotNull{std::addressof(arr[0])}, details::extent_type<N>())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <std::size_t N, class ArrayElementType = std::remove_const_t<element_type>>
|
template <std::size_t N, class = std::enable_if_t<(N > 0)>>
|
||||||
// GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute // TODO: parser bug
|
constexpr span(std::array<std::remove_const_t<element_type>, N>& arr) noexcept
|
||||||
constexpr span(std::array<ArrayElementType, N>& arr) noexcept
|
: storage_(KnownNotNull{arr.data()}, details::extent_type<N>())
|
||||||
: storage_(arr.data(), details::extent_type<N>())
|
{
|
||||||
{}
|
}
|
||||||
|
|
||||||
template <std::size_t N>
|
constexpr span(std::array<std::remove_const_t<element_type>, 0>&) noexcept
|
||||||
// GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute // TODO: parser bug
|
: storage_(static_cast<pointer>(nullptr), details::extent_type<0>())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t N, class = std::enable_if_t<(N > 0)>>
|
||||||
constexpr span(const std::array<std::remove_const_t<element_type>, N>& arr) noexcept
|
constexpr span(const std::array<std::remove_const_t<element_type>, N>& arr) noexcept
|
||||||
: storage_(arr.data(), details::extent_type<N>())
|
: storage_(KnownNotNull{arr.data()}, details::extent_type<N>())
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr span(const std::array<std::remove_const_t<element_type>, 0>&) noexcept
|
||||||
|
: storage_(static_cast<pointer>(nullptr), details::extent_type<0>())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
// NB: the SFINAE here uses .data() as a incomplete/imperfect proxy for the requirement
|
// NB: the SFINAE here uses .data() as a incomplete/imperfect proxy for the requirement
|
||||||
// on Container to be a contiguous sequence container.
|
// on Container to be a contiguous sequence container.
|
||||||
|
@ -452,6 +452,12 @@ TEST_CASE("from_std_array_constructor")
|
|||||||
CHECK((cs.size() == narrow_cast<ptrdiff_t>(arr.size()) && cs.data() == arr.data()));
|
CHECK((cs.size() == narrow_cast<ptrdiff_t>(arr.size()) && cs.data() == arr.data()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::array<int, 0> empty_arr{};
|
||||||
|
span<int> s{empty_arr};
|
||||||
|
CHECK((s.size() == 0 && s.empty()));
|
||||||
|
}
|
||||||
|
|
||||||
std::array<AddressOverloaded, 4> ao_arr{};
|
std::array<AddressOverloaded, 4> ao_arr{};
|
||||||
|
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user