multi_span: Add constexpr to BoundsRanges members

This commit is contained in:
Ben Klein 2017-12-04 13:04:38 -05:00
parent 210cc08a49
commit eaf91e0b8c

View File

@ -279,42 +279,42 @@ namespace details
struct BoundsRanges struct BoundsRanges
{ {
using size_type = std::ptrdiff_t; using size_type = std::ptrdiff_t;
static const size_type Depth = 0; static constexpr size_type Depth = 0;
static const size_type DynamicNum = 0; static constexpr size_type DynamicNum = 0;
static const size_type CurrentRange = 1; static constexpr size_type CurrentRange = 1;
static const size_type TotalSize = 1; static constexpr size_type TotalSize = 1;
// 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() = default; constexpr BoundsRanges() = 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 GSL_NOEXCEPT { return 0; } constexpr size_type elementNum(std::size_t) const GSL_NOEXCEPT { return 0; }
size_type totalSize() const GSL_NOEXCEPT { return TotalSize; } constexpr size_type totalSize() const GSL_NOEXCEPT { return TotalSize; }
bool operator==(const BoundsRanges&) const GSL_NOEXCEPT { return true; } constexpr bool operator==(const BoundsRanges&) const GSL_NOEXCEPT { return true; }
}; };
template <std::ptrdiff_t... RestRanges> template <std::ptrdiff_t... RestRanges>
@ -322,10 +322,10 @@ namespace details
{ {
using Base = BoundsRanges<RestRanges...>; using Base = BoundsRanges<RestRanges...>;
using size_type = std::ptrdiff_t; using size_type = std::ptrdiff_t;
static const std::size_t Depth = Base::Depth + 1; static constexpr std::size_t Depth = Base::Depth + 1;
static const std::size_t DynamicNum = Base::DynamicNum + 1; static constexpr std::size_t DynamicNum = Base::DynamicNum + 1;
static const size_type CurrentRange = dynamic_range; static constexpr size_type CurrentRange = dynamic_range;
static const size_type TotalSize = dynamic_range; static constexpr size_type TotalSize = dynamic_range;
private: private:
size_type m_bound; size_type m_bound;
@ -373,9 +373,9 @@ namespace details
size_type totalSize() const GSL_NOEXCEPT { return m_bound; } size_type totalSize() const GSL_NOEXCEPT { return m_bound; }
size_type elementNum() const GSL_NOEXCEPT { return totalSize() / this->Base::totalSize(); } constexpr size_type elementNum() const GSL_NOEXCEPT { return totalSize() / this->Base::totalSize(); }
size_type elementNum(std::size_t dim) const GSL_NOEXCEPT constexpr size_type elementNum(std::size_t dim) const GSL_NOEXCEPT
{ {
if (dim > 0) if (dim > 0)
return this->Base::elementNum(dim - 1); return this->Base::elementNum(dim - 1);
@ -383,7 +383,7 @@ namespace details
return elementNum(); return elementNum();
} }
bool operator==(const BoundsRanges& rhs) const GSL_NOEXCEPT constexpr bool operator==(const BoundsRanges& rhs) const GSL_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);
@ -395,17 +395,17 @@ namespace details
{ {
using Base = BoundsRanges<RestRanges...>; using Base = BoundsRanges<RestRanges...>;
using size_type = std::ptrdiff_t; using size_type = std::ptrdiff_t;
static const std::size_t Depth = Base::Depth + 1; static constexpr std::size_t Depth = Base::Depth + 1;
static const std::size_t DynamicNum = Base::DynamicNum; static constexpr std::size_t DynamicNum = Base::DynamicNum;
static const size_type CurrentRange = CurRange; static constexpr size_type CurrentRange = CurRange;
static const size_type TotalSize = static constexpr 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)
{ {
@ -413,14 +413,14 @@ 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
{ {
Expects(arr[Dim] >= 0 && arr[Dim] < CurrentRange); // Index is out of range Expects(arr[Dim] >= 0 && arr[Dim] < CurrentRange); // Index is out of range
return this->Base::totalSize() * arr[Dim] + return this->Base::totalSize() * arr[Dim] +
@ -428,7 +428,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
{ {
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);
@ -436,11 +436,11 @@ namespace details
return this->Base::totalSize() * arr[Dim] + last; return this->Base::totalSize() * arr[Dim] + last;
} }
size_type totalSize() const GSL_NOEXCEPT { return CurrentRange * this->Base::totalSize(); } constexpr size_type totalSize() const GSL_NOEXCEPT { return CurrentRange * this->Base::totalSize(); }
size_type elementNum() const GSL_NOEXCEPT { return CurrentRange; } constexpr size_type elementNum() const GSL_NOEXCEPT { return CurrentRange; }
size_type elementNum(std::size_t dim) const GSL_NOEXCEPT constexpr size_type elementNum(std::size_t dim) const GSL_NOEXCEPT
{ {
if (dim > 0) if (dim > 0)
return this->Base::elementNum(dim - 1); return this->Base::elementNum(dim - 1);
@ -448,7 +448,7 @@ namespace details
return elementNum(); return elementNum();
} }
bool operator==(const BoundsRanges& rhs) const GSL_NOEXCEPT constexpr bool operator==(const BoundsRanges& rhs) const GSL_NOEXCEPT
{ {
return static_cast<const Base&>(*this) == static_cast<const Base&>(rhs); return static_cast<const Base&>(*this) == static_cast<const Base&>(rhs);
} }
@ -467,31 +467,31 @@ namespace details
struct TypeListIndexer struct TypeListIndexer
{ {
const TypeChain& obj_; const TypeChain& obj_;
TypeListIndexer(const TypeChain& obj) : obj_(obj) {} constexpr TypeListIndexer(const TypeChain& obj) : obj_(obj) {}
template <std::size_t N> template <std::size_t N>
const TypeChain& getObj(std::true_type) constexpr const TypeChain& getObj(std::true_type)
{ {
return obj_; return obj_;
} }
template <std::size_t N, typename MyChain = TypeChain, template <std::size_t N, typename MyChain = TypeChain,
typename MyBase = typename MyChain::Base> typename MyBase = typename MyChain::Base>
auto getObj(std::false_type) constexpr auto getObj(std::false_type)
-> decltype(TypeListIndexer<MyBase>(static_cast<const MyBase&>(obj_)).template get<N>()) -> decltype(TypeListIndexer<MyBase>(static_cast<const MyBase&>(obj_)).template get<N>())
{ {
return TypeListIndexer<MyBase>(static_cast<const MyBase&>(obj_)).template get<N>(); return TypeListIndexer<MyBase>(static_cast<const MyBase&>(obj_)).template get<N>();
} }
template <std::size_t N> template <std::size_t N>
auto get() -> decltype(getObj<N - 1>(std::integral_constant<bool, N == 0>())) constexpr auto get() -> decltype(getObj<N - 1>(std::integral_constant<bool, N == 0>()))
{ {
return getObj<N - 1>(std::integral_constant<bool, N == 0>()); return getObj<N - 1>(std::integral_constant<bool, N == 0>());
} }
}; };
template <typename TypeChain> template <typename TypeChain>
TypeListIndexer<TypeChain> createTypeListIndexer(const TypeChain& obj) constexpr TypeListIndexer<TypeChain> createTypeListIndexer(const TypeChain& obj)
{ {
return TypeListIndexer<TypeChain>(obj); return TypeListIndexer<TypeChain>(obj);
} }