From 51da13607c655e8b57e82d1243b9283421182c27 Mon Sep 17 00:00:00 2001 From: Treb Connell Date: Thu, 24 Sep 2015 18:08:34 -0700 Subject: [PATCH 01/11] Fix issue #39: Add header guards --- include/array_view.h | 5 +++++ include/fail_fast.h | 5 +++++ include/gsl.h | 5 +++++ include/string_view.h | 5 +++++ 4 files changed, 20 insertions(+) diff --git a/include/array_view.h b/include/array_view.h index 006f18c..26a1641 100644 --- a/include/array_view.h +++ b/include/array_view.h @@ -16,6 +16,9 @@ #pragma once +#ifndef GSL_ARRAY_VIEW_H +#define GSL_ARRAY_VIEW_H + #include #include #include @@ -2286,3 +2289,5 @@ general_array_view_iterator operator+(typename general_array_view_ite #endif // _MSC_VER <= 1800 #pragma pop_macro("_NOEXCEPT") + +#endif // GSL_ARRAY_VIEW_H diff --git a/include/fail_fast.h b/include/fail_fast.h index dfd0ede..78a5102 100644 --- a/include/fail_fast.h +++ b/include/fail_fast.h @@ -16,6 +16,9 @@ #pragma once +#ifndef GSL_FAIL_FAST_H +#define GSL_FAIL_FAST_H + #include #include @@ -45,3 +48,5 @@ inline void fail_fast_assert(bool cond, const char* const) { if (!cond) std::ter #endif // SAFER_CPP_TESTING } + +#endif // GSL_FAIL_FAST_H diff --git a/include/gsl.h b/include/gsl.h index 1357d76..09a46c7 100644 --- a/include/gsl.h +++ b/include/gsl.h @@ -16,6 +16,9 @@ #pragma once +#ifndef GSL_GSL_H +#define GSL_GSL_H + #include "array_view.h" // array_view, strided_array_view... #include "string_view.h" // zstring, string_view, zstring_builder... #include @@ -287,3 +290,5 @@ private: template using maybe_null = maybe_null_ret; } // namespace Guide + +#endif // GSL_GSL_H diff --git a/include/string_view.h b/include/string_view.h index 7becc8e..e683c7a 100644 --- a/include/string_view.h +++ b/include/string_view.h @@ -16,6 +16,9 @@ #pragma once +#ifndef GSL_STRING_VIEW_H +#define GSL_STRING_VIEW_H + #include "array_view.h" #include @@ -176,3 +179,5 @@ using zstring_builder = basic_zstring_builder; template using wzstring_builder = basic_zstring_builder; } + +#endif // GSL_STRING_VIEW_H From e1570268077b2b063f7397a804fe17690b2ddc9e Mon Sep 17 00:00:00 2001 From: Kern Handa Date: Fri, 25 Sep 2015 00:42:38 -0700 Subject: [PATCH 02/11] Rank and dimensions should be size_t. --- include/array_view.h | 132 +++++++++++++++++++++---------------------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/include/array_view.h b/include/array_view.h index 006f18c..f9eadc4 100644 --- a/include/array_view.h +++ b/include/array_view.h @@ -71,20 +71,20 @@ namespace details }; - template + template class coordinate_facade { static_assert(std::is_integral::value && sizeof(ValueType) <= sizeof(size_t), "ValueType must be unsigned integral type!"); static_assert(Rank > 0, "Rank must be greater than 0!"); - template + template friend class coordinate_facade; public: using reference = ValueType&; using const_reference = const ValueType&; using value_type = ValueType; - static const unsigned int rank = Rank; + static const size_t rank = Rank; _CONSTEXPR coordinate_facade() _NOEXCEPT { static_assert(std::is_base_of::value, "ConcreteType must be derived from coordinate_facade."); @@ -92,7 +92,7 @@ namespace details _CONSTEXPR coordinate_facade(const value_type(&values)[rank]) _NOEXCEPT { static_assert(std::is_base_of::value, "ConcreteType must be derived from coordinate_facade."); - for (unsigned int i = 0; i < rank; ++i) + for (size_t i = 0; i < rank; ++i) elems[i] = values[i]; } _CONSTEXPR coordinate_facade(value_type e0) _NOEXCEPT @@ -106,7 +106,7 @@ namespace details { static_assert(std::is_base_of::value, "ConcreteType must be derived from coordinate_facade."); fail_fast_assert(il.size() == rank, "The size of the initializer list must match the rank of the array"); - for (unsigned int i = 0; i < rank; ++i) + for (size_t i = 0; i < rank; ++i) { elems[i] = begin(il)[i]; } @@ -117,7 +117,7 @@ namespace details template _CONSTEXPR coordinate_facade(const coordinate_facade & other) { - for (unsigned int i = 0; i < rank; ++i) + for (size_t i = 0; i < rank; ++i) { fail_fast_assert(static_cast(other.elems[i]) <= SizeTypeTraits::max_value); elems[i] = static_cast(other.elems[i]); @@ -126,20 +126,20 @@ namespace details protected: coordinate_facade& operator=(const coordinate_facade& rhs) = default; // Preconditions: component_idx < rank - _CONSTEXPR reference operator[](unsigned int component_idx) + _CONSTEXPR reference operator[](size_t component_idx) { fail_fast_assert(component_idx < rank, "Component index must be less than rank"); return elems[component_idx]; } // Preconditions: component_idx < rank - _CONSTEXPR const_reference operator[](unsigned int component_idx) const + _CONSTEXPR const_reference operator[](size_t component_idx) const { fail_fast_assert(component_idx < rank, "Component index must be less than rank"); return elems[component_idx]; } _CONSTEXPR bool operator==(const ConcreteType& rhs) const _NOEXCEPT { - for (unsigned int i = 0; i < rank; ++i) + for (size_t i = 0; i < rank; ++i) { if (elems[i] != rhs.elems[i]) return false; @@ -157,7 +157,7 @@ namespace details _CONSTEXPR ConcreteType operator-() const { ConcreteType ret = to_concrete(); - for (unsigned int i = 0; i < rank; ++i) + for (size_t i = 0; i < rank; ++i) ret.elems[i] = -ret.elems[i]; return ret; } @@ -175,13 +175,13 @@ namespace details } _CONSTEXPR ConcreteType& operator+=(const ConcreteType& rhs) { - for (unsigned int i = 0; i < rank; ++i) + for (size_t i = 0; i < rank; ++i) elems[i] += rhs.elems[i]; return to_concrete(); } _CONSTEXPR ConcreteType& operator-=(const ConcreteType& rhs) { - for (unsigned int i = 0; i < rank; ++i) + for (size_t i = 0; i < rank; ++i) elems[i] -= rhs.elems[i]; return to_concrete(); } @@ -229,13 +229,13 @@ namespace details } _CONSTEXPR ConcreteType& operator*=(value_type v) { - for (unsigned int i = 0; i < rank; ++i) + for (size_t i = 0; i < rank; ++i) elems[i] *= v; return to_concrete(); } _CONSTEXPR ConcreteType& operator/=(value_type v) { - for (unsigned int i = 0; i < rank; ++i) + for (size_t i = 0; i < rank; ++i) elems[i] /= v; return to_concrete(); } @@ -270,12 +270,12 @@ namespace details }; } -template +template class index : private details::coordinate_facade, ValueType, Rank> { using Base = details::coordinate_facade, ValueType, Rank>; friend Base; - template + template friend class index; public: using Base::rank; @@ -317,10 +317,10 @@ public: template class index<1, ValueType> { - template + template friend class index; public: - static const unsigned int rank = 1; + static const size_t rank = 1; using reference = ValueType&; using const_reference = const ValueType&; using size_type = ValueType; @@ -537,8 +537,8 @@ namespace details template struct BoundsRanges { - static const unsigned int Depth = 0; - static const unsigned int DynamicNum = 0; + static const size_t Depth = 0; + static const size_t DynamicNum = 0; static const SizeType CurrentRange = 1; static const SizeType TotalSize = 1; @@ -551,14 +551,14 @@ namespace details BoundsRanges() = default; - template + template void serialize(T &) const { } - template + template SizeType linearize(const T &) const { return 0; } - template + template ptrdiff_t contains(const T &) const { return 0; } @@ -576,8 +576,8 @@ namespace details template struct BoundsRanges : BoundsRanges{ using Base = BoundsRanges ; - static const unsigned int Depth = Base::Depth + 1; - static const unsigned int DynamicNum = Base::DynamicNum + 1; + static const size_t Depth = Base::Depth + 1; + static const size_t DynamicNum = Base::DynamicNum + 1; static const SizeType CurrentRange = dynamic_range; static const SizeType TotalSize = dynamic_range; const SizeType m_bound; @@ -596,19 +596,19 @@ namespace details { } - template + template void serialize(T & arr) const { arr[Dim] = elementNum(); this->Base::template serialize(arr); } - template + template SizeType linearize(const T & arr) const { const size_t index = this->Base::totalSize() * arr[Dim]; fail_fast_assert(index < static_cast(m_bound)); return static_cast(index) + this->Base::template linearize(arr); } - template + template ptrdiff_t contains(const T & arr) const { const ptrdiff_t last = this->Base::template contains(arr); if (last == -1) @@ -625,7 +625,7 @@ namespace details return static_cast(totalSize() / this->Base::totalSize()); } - SizeType elementNum(unsigned int dim) const _NOEXCEPT{ + SizeType elementNum(size_t dim) const _NOEXCEPT{ if (dim > 0) return this->Base::elementNum(dim - 1); else @@ -641,8 +641,8 @@ namespace details template struct BoundsRanges : BoundsRanges{ using Base = BoundsRanges ; - static const unsigned int Depth = Base::Depth + 1; - static const unsigned int DynamicNum = Base::DynamicNum; + static const size_t Depth = Base::Depth + 1; + static const size_t DynamicNum = Base::DynamicNum; static const SizeType CurrentRange = static_cast(CurRange); static const SizeType TotalSize = StaticSizeHelper::value; static_assert (CurRange <= SizeTypeTraits::max_value, "CurRange must be smaller than SizeType limits"); @@ -657,19 +657,19 @@ namespace details fail_fast_assert((firstLevel && totalSize() <= other.totalSize()) || totalSize() == other.totalSize()); } - template + template void serialize(T & arr) const { arr[Dim] = elementNum(); this->Base::template serialize(arr); } - template + template SizeType linearize(const T & arr) const { fail_fast_assert(arr[Dim] < CurrentRange, "Index is out of range"); return static_cast(this->Base::totalSize()) * arr[Dim] + this->Base::template linearize(arr); } - template + template ptrdiff_t contains(const T & arr) const { if (static_cast(arr[Dim]) >= CurrentRange) return -1; @@ -687,7 +687,7 @@ namespace details return CurrentRange; } - SizeType elementNum(unsigned int dim) const _NOEXCEPT{ + SizeType elementNum(size_t dim) const _NOEXCEPT{ if (dim > 0) return this->Base::elementNum(dim - 1); else @@ -732,17 +732,17 @@ namespace details { const TypeChain & obj; TypeListIndexer(const TypeChain & obj) :obj(obj){} - template + template const TypeChain & getObj(std::true_type) { return obj; } - template + template auto getObj(std::false_type) -> decltype(TypeListIndexer(static_cast(obj)).template get()) { return TypeListIndexer(static_cast(obj)).template get(); } - template + template auto get() -> decltype(getObj(std::integral_constant())) { return getObj(std::integral_constant()); @@ -779,8 +779,8 @@ class static_bounds template friend class static_bounds; public: - static const unsigned int rank = MyRanges::Depth; - static const unsigned int dynamic_rank = MyRanges::DynamicNum; + static const size_t rank = MyRanges::Depth; + static const size_t dynamic_rank = MyRanges::DynamicNum; static const SizeType static_size = static_cast(MyRanges::TotalSize); using size_type = SizeType; @@ -844,12 +844,12 @@ public: return m_ranges.contains(idx) != -1; } - _CONSTEXPR size_type operator[](unsigned int index) const _NOEXCEPT + _CONSTEXPR size_type operator[](size_t index) const _NOEXCEPT { return m_ranges.elementNum(index); } - template + template _CONSTEXPR size_type extent() const _NOEXCEPT { static_assert(Dim < rank, "dimension should be less than rank (dimension count starts from 0)"); @@ -888,12 +888,12 @@ public: } }; -template +template class strided_bounds : private details::coordinate_facade, SizeType, Rank> { using Base = details::coordinate_facade, SizeType, Rank>; friend Base; - template + template friend class strided_bounds; public: @@ -921,7 +921,7 @@ public: _CONSTEXPR strided_bounds(const index_type &extents, const index_type &strides) : m_strides(strides) { - for (unsigned int i = 0; i < rank; i++) + for (size_t i = 0; i < rank; i++) Base::elems[i] = extents[i]; } _CONSTEXPR strided_bounds(const value_type(&values)[rank], index_type strides) @@ -935,20 +935,20 @@ public: _CONSTEXPR size_type total_size() const _NOEXCEPT { size_type ret = 0; - for (unsigned int i = 0; i < rank; ++i) + for (size_t i = 0; i < rank; ++i) ret += (Base::elems[i] - 1) * m_strides[i]; return ret + 1; } _CONSTEXPR size_type size() const _NOEXCEPT { size_type ret = 1; - for (unsigned int i = 0; i < rank; ++i) + for (size_t i = 0; i < rank; ++i) ret *= Base::elems[i]; return ret; } _CONSTEXPR bool contains(const index_type& idx) const _NOEXCEPT { - for (unsigned int i = 0; i < rank; ++i) + for (size_t i = 0; i < rank; ++i) { if (idx[i] < 0 || idx[i] >= Base::elems[i]) return false; @@ -958,7 +958,7 @@ public: _CONSTEXPR size_type linearize(const index_type & idx) const { size_type ret = 0; - for (unsigned int i = 0; i < rank; i++) + for (size_t i = 0; i < rank; i++) { fail_fast_assert(idx[i] < Base::elems[i], "index is out of bounds of the array"); ret += idx[i] * m_strides[i]; @@ -974,7 +974,7 @@ public: { return{ (value_type(&)[rank - 1])Base::elems[1], sliced_type::index_type::shift_left(m_strides) }; } - template + template _CONSTEXPR size_type extent() const _NOEXCEPT { static_assert(Dim < Rank, "dimension should be less than rank (dimension count starts from 0)"); @@ -1000,7 +1000,7 @@ template struct is_bounds : std::integral_constant {}; template struct is_bounds> : std::integral_constant {}; -template +template struct is_bounds> : std::integral_constant {}; template @@ -1014,7 +1014,7 @@ class bounds_iterator private: using Base = std::iterator , const IndexType>; public: - static const unsigned int rank = IndexType::rank; + static const size_t rank = IndexType::rank; using typename Base::reference; using typename Base::pointer; using typename Base::difference_type; @@ -1038,7 +1038,7 @@ public: } bounds_iterator& operator++() _NOEXCEPT { - for (unsigned int i = rank; i-- > 0;) + for (size_t i = rank; i-- > 0;) { if (++curr[i] < boundary[i]) { @@ -1050,7 +1050,7 @@ public: } } // If we're here we've wrapped over - set to past-the-end. - for (unsigned int i = 0; i < rank; ++i) + for (size_t i = 0; i < rank; ++i) { curr[i] = boundary[i]; } @@ -1096,11 +1096,11 @@ public: auto linear_idx = linearize(curr) + n; value_type stride; stride[rank - 1] = 1; - for (unsigned int i = rank - 1; i-- > 0;) + for (size_t i = rank - 1; i-- > 0;) { stride[i] = stride[i + 1] * boundary[i + 1]; } - for (unsigned int i = 0; i < rank; ++i) + for (size_t i = 0; i < rank; ++i) { curr[i] = linear_idx / stride[i]; linear_idx = linear_idx % stride[i]; @@ -1134,7 +1134,7 @@ public: } bool operator<(const bounds_iterator& rhs) const _NOEXCEPT { - for (unsigned int i = 0; i < rank; ++i) + for (size_t i = 0; i < rank; ++i) { if (curr[i] < rhs.curr[i]) return true; @@ -1164,7 +1164,7 @@ private: // TODO: Smarter impl. // Check if past-the-end bool pte = true; - for (unsigned int i = 0; i < rank; ++i) + for (size_t i = 0; i < rank; ++i) { if (idx[i] != boundary[i]) { @@ -1177,7 +1177,7 @@ private: if (pte) { res = 1; - for (unsigned int i = rank; i-- > 0;) + for (size_t i = rank; i-- > 0;) { res += (idx[i] - 1) * multiplier; multiplier *= boundary[i]; @@ -1185,7 +1185,7 @@ private: } else { - for (unsigned int i = rank; i-- > 0;) + for (size_t i = rank; i-- > 0;) { res += idx[i] * multiplier; multiplier *= boundary[i]; @@ -1359,7 +1359,7 @@ template class basic_array_view { public: - static const unsigned int rank = BoundsType::rank; + static const size_t rank = BoundsType::rank; using bounds_type = BoundsType; using size_type = typename bounds_type::size_type; using index_type = typename bounds_type::index_type; @@ -1381,7 +1381,7 @@ public: { return m_bounds; } - template + template _CONSTEXPR size_type extent() const _NOEXCEPT { static_assert(Dim < rank, "dimension should be less than rank (dimension count starts from 0)"); @@ -1537,7 +1537,7 @@ struct dim template class array_view; -template +template class strided_array_view; namespace details @@ -1616,7 +1616,7 @@ namespace details template struct is_array_view_oracle> : std::true_type {}; - template + template struct is_array_view_oracle> : std::true_type {}; template @@ -1930,12 +1930,12 @@ template _CONSTEXPR auto as_array_view(Cont &&arr) -> std::enable_if_t>::value, array_view, dynamic_range>> = delete; -template +template class strided_array_view : public basic_array_view::value_type, strided_bounds::size_type>> { using Base = basic_array_view::value_type, strided_bounds::size_type>>; - template + template friend class strided_array_view; public: using Base::rank; From 437791e504462b2585808a717b61e084692638be Mon Sep 17 00:00:00 2001 From: saurabh singh Date: Sun, 27 Sep 2015 16:11:12 +0530 Subject: [PATCH 03/11] GSL::finally can make use of move semantics for eg consider this case [code] string value = "someVeryLongErrorMessageIAm"; finally([value] { PrintErrorMessage(value); } [/code] With the current changes before the call to PrintErrorMessage there will be 3 calls to copy constructor for string(1 when it's captured in closure, 2nd when finally is called and 3rd when it's passed to Final_act . With my patch there will be 1 call to the copy constructor and 2 to the move constructor for the scenario in example, so 2 potential deep copies will be saved for some objects. Validated that code builds from root, and all tests pass after my change. Also validated that indeed copy constructor calls are saved for objects that support move semantics. --- include/gsl.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/gsl.h b/include/gsl.h index 09a46c7..23b62a9 100644 --- a/include/gsl.h +++ b/include/gsl.h @@ -50,7 +50,7 @@ template class Final_act { public: - explicit Final_act(F f) : f_(f) {} + explicit Final_act(F f) : f_(std::move(f)) {} Final_act(const Final_act&& other) : f_(other.f_) {} Final_act(const Final_act&) = delete; @@ -64,7 +64,10 @@ private: // finally() - convenience function to generate a Final_act template -Final_act finally(F f) { return Final_act(f); } +Final_act finally(const F &f) { return Final_act(f); } + +template +Final_act finally(F &&f) { return Final_act(std::forward(f)); } // narrow_cast(): a searchable way to do narrowing casts of values template From 2b6d90436f3f0b0444efc918203663367e823b65 Mon Sep 17 00:00:00 2001 From: Kern Handa Date: Fri, 25 Sep 2015 09:41:40 -0700 Subject: [PATCH 04/11] not_null and maybe_null variants should only work on nullptr-assignable types. This is in accordance with the GSL.View guidance on not_null and maybe_null types in the CppCoreGuidelines document. --- include/gsl.h | 3 +++ tests/maybenull_tests.cpp | 13 +++++++++++++ tests/notnull_tests.cpp | 8 ++++++++ 3 files changed, 24 insertions(+) diff --git a/include/gsl.h b/include/gsl.h index 23b62a9..fed3b6c 100644 --- a/include/gsl.h +++ b/include/gsl.h @@ -108,6 +108,7 @@ typename Cont::value_type& at(Cont& cont, size_t index) { fail_fast_assert(index template class not_null { + static_assert(std::is_assignable::value, "T cannot be assigned nullptr."); public: not_null(T t) : ptr_(t) { ensure_invariant(); } @@ -168,6 +169,7 @@ private: template class maybe_null_dbg { + static_assert(std::is_assignable::value, "T cannot be assigned nullptr."); public: maybe_null_dbg() : ptr_(nullptr), tested_(false) {} @@ -243,6 +245,7 @@ private: template class maybe_null_ret { + static_assert(std::is_assignable::value, "T cannot be assigned nullptr."); public: maybe_null_ret() : ptr_(nullptr) {} maybe_null_ret(std::nullptr_t) : ptr_(nullptr) {} diff --git a/tests/maybenull_tests.cpp b/tests/maybenull_tests.cpp index 0a9d891..4b74114 100644 --- a/tests/maybenull_tests.cpp +++ b/tests/maybenull_tests.cpp @@ -16,6 +16,7 @@ #include #include +#include using namespace Guide; @@ -27,12 +28,24 @@ SUITE(MaybeNullTests) { TEST(TestMaybeNull1) { +#ifdef CONFIRM_COMPILATION_ERRORS + // Forbid non-nullptr assignable types + maybe_null_ret> f_ret(std::vector{1}); + maybe_null_ret> f_ret(std::vector{1}); + maybe_null_ret z_ret(10); + maybe_null_dbg> y_dbg({1,2}); + maybe_null_dbg z_dbg(10); + maybe_null_dbg> y_dbg({1,2}); +#endif int n = 5; maybe_null_dbg opt_n(&n); int result = 0; bool threw = false; CHECK_THROW(result = *opt_n, fail_fast); + + maybe_null_ret> x_ret(std::make_shared(10)); // shared_ptr is nullptr assignable + maybe_null_dbg> x_dbg(std::make_shared(10)); // shared_ptr is nullptr assignable } TEST(TestMaybeNull2) diff --git a/tests/notnull_tests.cpp b/tests/notnull_tests.cpp index 008cbb3..7232840 100644 --- a/tests/notnull_tests.cpp +++ b/tests/notnull_tests.cpp @@ -16,6 +16,7 @@ #include #include +#include using namespace Guide; @@ -48,11 +49,18 @@ SUITE(NotNullTests) not_null p; // yay...does not compile! std::unique_ptr up = std::make_unique(120); not_null p = up; + + // Forbid non-nullptr assignable types + not_null> f(std::vector{1}); + not_null z(10); + not_null> y({1,2}); #endif int i = 12; auto rp = RefCounted(&i); not_null p(rp); CHECK(p.get() == &i); + + not_null> x(std::make_shared(10)); // shared_ptr is nullptr assignable } TEST(TestNotNullCasting) From fb91393bb205ea6a19cda4c92db5899519be9bdc Mon Sep 17 00:00:00 2001 From: Neil MacIntosh Date: Sun, 27 Sep 2015 16:25:43 -0700 Subject: [PATCH 05/11] Fixing size_t/int mismatch in loops. --- include/array_view.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/array_view.h b/include/array_view.h index e40918d..68a3cf0 100644 --- a/include/array_view.h +++ b/include/array_view.h @@ -1067,7 +1067,7 @@ public: } bounds_iterator& operator--() _NOEXCEPT { - for (int i = rank; i-- > 0;) + for (size_t i = rank; i-- > 0;) { if (curr[i]-- > 0) { @@ -1335,7 +1335,7 @@ namespace details auto extents = bnd.index_bounds(); typename Bounds::index_type stride; stride[Bounds::rank - 1] = 1; - for (int i = Bounds::rank - 2; i >= 0; --i) + for (size_t i = Bounds::rank - 2; i >= 0; --i) stride[i] = stride[i + 1] * extents[i + 1]; return stride; } @@ -2035,7 +2035,7 @@ private: fail_fast_assert(strides[rank - 1] == 1, "Only strided arrays with regular strides can be resized"); fail_fast_assert(strides[rank - 2] >= d && (strides[rank - 2] % d == 0), "The strides must have contiguous chunks of memory that can contain a multiple of new type elements"); - for (int i = rank - 2; i >= 0; --i) + for (size_t i = rank - 2; i >= 0; --i) { fail_fast_assert((strides[i] >= strides[i + 1]) && (strides[i] % strides[i + 1] == 0), "Only strided arrays with regular strides can be resized"); } From 99746e2d57a3068d1130dce4bf5b1e46a86cf9d2 Mon Sep 17 00:00:00 2001 From: Neil MacIntosh Date: Sun, 27 Sep 2015 16:53:58 -0700 Subject: [PATCH 06/11] Correct fix for int/size_t mismatch. --- include/array_view.h | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/include/array_view.h b/include/array_view.h index 68a3cf0..038b6e4 100644 --- a/include/array_view.h +++ b/include/array_view.h @@ -1328,15 +1328,15 @@ namespace details return bnd.strides(); } - // Make a stride vector from bounds, assuming continugous memory. + // Make a stride vector from bounds, assuming contiguous memory. template _CONSTEXPR std::enable_if_t::value, typename Bounds::index_type> make_stride(const Bounds& bnd) _NOEXCEPT { auto extents = bnd.index_bounds(); typename Bounds::index_type stride; stride[Bounds::rank - 1] = 1; - for (size_t i = Bounds::rank - 2; i >= 0; --i) - stride[i] = stride[i + 1] * extents[i + 1]; + for (size_t i = Bounds::rank - 1; Bounds::rank > 1 && i > 0; --i) + stride[i-1] = stride[i] * extents[i]; return stride; } @@ -2035,10 +2035,8 @@ private: fail_fast_assert(strides[rank - 1] == 1, "Only strided arrays with regular strides can be resized"); fail_fast_assert(strides[rank - 2] >= d && (strides[rank - 2] % d == 0), "The strides must have contiguous chunks of memory that can contain a multiple of new type elements"); - for (size_t i = rank - 2; i >= 0; --i) - { - fail_fast_assert((strides[i] >= strides[i + 1]) && (strides[i] % strides[i + 1] == 0), "Only strided arrays with regular strides can be resized"); - } + for (size_t i = rank - 1; i > 0; --i) + fail_fast_assert((strides[i-1] >= strides[i]) && (strides[i-1] % strides[i] == 0), "Only strided arrays with regular strides can be resized"); index_type ret = strides / d; ret[rank - 1] = 1; From bb169976da75c4c8a30b403ffc8ff887d72a75bf Mon Sep 17 00:00:00 2001 From: Neil MacIntosh Date: Sun, 27 Sep 2015 18:06:51 -0700 Subject: [PATCH 07/11] Fixed leak in owner<> test. Ha ha ha! --- tests/owner_tests.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/owner_tests.cpp b/tests/owner_tests.cpp index 430b31a..d985533 100644 --- a/tests/owner_tests.cpp +++ b/tests/owner_tests.cpp @@ -33,6 +33,7 @@ SUITE(owner_tests) CHECK(*p == 120); f(p); CHECK(*p == 121); + delete p; } } From 783eaabf9d7b40403540f2164fb096c3150d4c94 Mon Sep 17 00:00:00 2001 From: Kern Handa Date: Mon, 28 Sep 2015 07:35:18 +0000 Subject: [PATCH 08/11] Add various copy assignment operators to not_null and maybe_null_*. Also removed unused constant member variable that seemed to be there to prevent maybe_null_* being used with anything other than a pointer, which is being taken care of with a static_assert now. --- include/gsl.h | 129 +++++++++++++++++++++++++++----------- tests/maybenull_tests.cpp | 38 +++++++++++ tests/notnull_tests.cpp | 11 +++- 3 files changed, 138 insertions(+), 40 deletions(-) diff --git a/include/gsl.h b/include/gsl.h index fed3b6c..bf3573e 100644 --- a/include/gsl.h +++ b/include/gsl.h @@ -111,21 +111,27 @@ class not_null static_assert(std::is_assignable::value, "T cannot be assigned nullptr."); public: not_null(T t) : ptr_(t) { ensure_invariant(); } - - // deleting these two prevents compilation when initialized with a nullptr or literal 0 - not_null(std::nullptr_t) = delete; - not_null(int) = delete; + not_null& operator=(const T& t) { ptr_ = t; ensure_invariant(); return *this; } not_null(const not_null &other) = default; + not_null& operator=(const not_null &other) = default; template ::value>> - not_null(const not_null &other) : ptr_(other.get()) + not_null(const not_null &other) { + *this = other; } - not_null& operator=(const T& t) { ptr_ = t; ensure_invariant(); return *this; } + template ::value>> + not_null& operator=(const not_null &other) + { + ptr_ = other.get(); + return *this; + } // prevents compilation when someone attempts to assign a nullptr + not_null(std::nullptr_t) = delete; + not_null(int) = delete; not_null& operator=(std::nullptr_t) = delete; not_null& operator=(int) = delete; @@ -166,26 +172,18 @@ private: // // Describes an optional pointer - provides symmetry with not_null // +template +class maybe_null_ret; + template class maybe_null_dbg { static_assert(std::is_assignable::value, "T cannot be assigned nullptr."); public: maybe_null_dbg() : ptr_(nullptr), tested_(false) {} + maybe_null_dbg(std::nullptr_t) : ptr_(nullptr), tested_(false) {} maybe_null_dbg(const T& p) : ptr_(p), tested_(false) {} - maybe_null_dbg(const maybe_null_dbg& rhs) : ptr_(rhs.ptr_), tested_(false) {} - - template ::value>> - maybe_null_dbg(const not_null &other) : ptr_(other.get()), tested_(false) - { - } - - template ::value>> - maybe_null_dbg(const maybe_null_dbg &other) : ptr_(other.get()), tested_(false) - { - } - maybe_null_dbg& operator=(const T& p) { if (ptr_ != p) @@ -196,6 +194,8 @@ public: return *this; } + + maybe_null_dbg(const maybe_null_dbg& rhs) : ptr_(rhs.ptr_), tested_(false) {} maybe_null_dbg& operator=(const maybe_null_dbg& rhs) { if (this != &rhs) @@ -206,6 +206,43 @@ public: return *this; } + + template ::value>> + maybe_null_dbg(const not_null &other) : ptr_(other.get()), tested_(false) {} + + template ::value>> + maybe_null_dbg& operator=(const not_null &other) + { + ptr_ = other.get(); + tested_ = false; + return *this; + } + + + template ::value>> + maybe_null_dbg(const maybe_null_dbg &other) : ptr_(other.get()), tested_(false) {} + + template ::value>> + maybe_null_dbg& operator=(const maybe_null_dbg &other) + { + ptr_ = other.get(); + tested_ = false; + return *this; + } + + + template ::value>> + maybe_null_dbg(const maybe_null_ret &other) : ptr_(other.get()), tested_(false) {} + + template ::value>> + maybe_null_dbg& operator=(const maybe_null_ret &other) + { + ptr_ = other.get(); + tested_ = false; + return *this; + } + + bool present() const { tested_ = true; return ptr_ != nullptr; } bool operator==(const T& rhs) const { tested_ = true; return ptr_ == rhs; } @@ -225,8 +262,6 @@ public: T operator->() const { return get(); } private: - const size_t ptee_size_ = sizeof(*ptr_); // T must be a pointer type - // unwanted operators...pointers only point to single objects! // TODO ensure all arithmetic ops on this type are unavailable maybe_null_dbg& operator++() = delete; @@ -249,27 +284,46 @@ class maybe_null_ret public: maybe_null_ret() : ptr_(nullptr) {} maybe_null_ret(std::nullptr_t) : ptr_(nullptr) {} + maybe_null_ret(const T& p) : ptr_(p) {} + maybe_null_ret& operator=(const T& p) { ptr_ = p; return *this; } + maybe_null_ret(const maybe_null_ret& rhs) = default; - - template ::value>> - maybe_null_ret(const not_null &other) : ptr_(other.get()) - { - } - - template ::value>> - maybe_null_ret(const maybe_null_ret &other) : ptr_(other.get()) - { - } - - template ::value>> - maybe_null_ret(const maybe_null_dbg &other) : ptr_(other.get()) - { - } - - maybe_null_ret& operator=(const T& p) { if (ptr_ != p) { ptr_ = p; } return *this; } maybe_null_ret& operator=(const maybe_null_ret& rhs) = default; + template ::value>> + maybe_null_ret(const not_null &other) : ptr_(other.get()) {} + + template ::value>> + maybe_null_ret& operator=(const not_null &other) + { + ptr_ = other.get(); + return *this; + } + + + template ::value>> + maybe_null_ret(const maybe_null_ret &other) : ptr_(other.get()) {} + + template ::value>> + maybe_null_ret& operator=(const maybe_null_ret &other) + { + ptr_ = other.get(); + return *this; + } + + + template ::value>> + maybe_null_ret(const maybe_null_dbg &other) : ptr_(other.get()) {} + + template ::value>> + maybe_null_ret& operator=(const maybe_null_dbg &other) + { + ptr_ = other.get(); + return *this; + } + + bool present() const { return ptr_ != nullptr; } T get() const { return ptr_; } @@ -289,7 +343,6 @@ private: maybe_null_ret& operator-(size_t) = delete; maybe_null_ret& operator-=(size_t) = delete; - const size_t ptee_size_ = sizeof(*ptr_); // T must be a pointer type T ptr_; }; diff --git a/tests/maybenull_tests.cpp b/tests/maybenull_tests.cpp index 4b74114..d6b53f0 100644 --- a/tests/maybenull_tests.cpp +++ b/tests/maybenull_tests.cpp @@ -17,6 +17,7 @@ #include #include #include +#include using namespace Guide; @@ -254,6 +255,43 @@ SUITE(MaybeNullTests) // Make sure we no longer throw here CHECK(p1.get() != nullptr); } + + TEST(TestMaybeNullAssignmentOps) + { + MyBase base; + MyDerived derived; + Unrelated unrelated; + + not_null nnBase(&base); + not_null nnDerived(&derived); + not_null nnUnrelated(&unrelated); + + maybe_null_ret mnBase_ret1(&base), mnBase_ret2; + mnBase_ret2 = mnBase_ret1; // maybe_null_ret = maybe_null_ret + mnBase_ret2 = nnBase; // maybe_null_ret = not_null + + maybe_null_ret mnDerived_ret(&derived); + mnBase_ret2 = mnDerived_ret; // maybe_null_ret = maybe_null_ret + mnBase_ret1 = &derived; // maybe_null_ret = U; + mnBase_ret1 = nnDerived; // maybe_null_ret = not_null + + maybe_null_ret mnUnrelated_ret; + mnUnrelated_ret = &unrelated; // maybe_null_ret = T + + maybe_null_dbg mnBase_dbg1(&base), mnBase_dbg2; + mnBase_dbg2 = mnBase_dbg1; // maybe_null_dbg = maybe_null_dbg + mnBase_dbg2 = nnBase; // maybe_null_dbg = not_null + + maybe_null_dbg mnDerived_dbg(&derived); + CHECK(mnDerived_dbg.present()); + mnBase_dbg2 = mnDerived_dbg; // maybe_null_dbg = maybe_null_dbg + + mnBase_dbg1 = &derived; // maybe_null_dbg = U; + mnBase_dbg1 = nnDerived; // maybe_null_dbg = not_null + + maybe_null_dbg mnUnrelated_dbg; + mnUnrelated_dbg = &unrelated; // maybe_null_dbg = T + } } int main(int, const char *[]) diff --git a/tests/notnull_tests.cpp b/tests/notnull_tests.cpp index 7232840..46011b6 100644 --- a/tests/notnull_tests.cpp +++ b/tests/notnull_tests.cpp @@ -65,12 +65,19 @@ SUITE(NotNullTests) TEST(TestNotNullCasting) { - MyDerived derived; + MyBase base; + MyDerived derived; + Unrelated unrelated; + not_null u = &unrelated; not_null p = &derived; - not_null q = p; + not_null q = &base; + q = p; // allowed with heterogeneous copy ctor CHECK(q == p); #ifdef CONFIRM_COMPILATION_ERRORS + q = u; // no viable conversion possible between MyBase* and Unrelated* + p = q; // not possible to implicitly convert MyBase* to MyDerived* + not_null r = p; not_null s = reinterpret_cast(p); #endif From 4e596761eb0ae42ff032c44c22dba9be5adc8733 Mon Sep 17 00:00:00 2001 From: Gabriel Dos Reis Date: Mon, 28 Sep 2015 04:43:50 -0700 Subject: [PATCH 09/11] Update list of known platforms where GSL was successfully tested --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a32e89f..7d96dec 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ The test suite that exercises GSL has been built and passes successfully on the * GNU/Linux using GCC 5.1 * OS X Yosemite using Xcode with AppleClang 7.0.0.7000072 * OS X Yosemite using GCC-5.2.0 +* FreeBSD 10.x with Clang/LLVM 3.6 > If you successfully port GSL to another platform, we would love to hear from you. Please submit an issue to let us know. Also please consider contributing any changes that were necessary back to this project to benefit the wider community. From 6554e83c79e680500691cb2b3411c3c14d82623f Mon Sep 17 00:00:00 2001 From: Gabriel Dos Reis Date: Mon, 28 Sep 2015 05:10:44 -0700 Subject: [PATCH 10/11] Macro expand `constexpr` to nothing under MSVC Replace `_CONSTEXPR` with plain `constexpr`. --- include/array_view.h | 334 ++++++++++++++++++++++--------------------- 1 file changed, 169 insertions(+), 165 deletions(-) diff --git a/include/array_view.h b/include/array_view.h index 038b6e4..8bfdc69 100644 --- a/include/array_view.h +++ b/include/array_view.h @@ -30,10 +30,9 @@ #include #include "fail_fast.h" -#ifndef _MSC_VER -#define _CONSTEXPR constexpr -#else -#define _CONSTEXPR +#if defined(_MSC_VER) +#pragma push_macro("constexpr") +#define constexpr /* nothing */ #endif #pragma push_macro("_NOEXCEPT") @@ -88,24 +87,24 @@ namespace details using const_reference = const ValueType&; using value_type = ValueType; static const size_t rank = Rank; - _CONSTEXPR coordinate_facade() _NOEXCEPT + constexpr coordinate_facade() _NOEXCEPT { static_assert(std::is_base_of::value, "ConcreteType must be derived from coordinate_facade."); } - _CONSTEXPR coordinate_facade(const value_type(&values)[rank]) _NOEXCEPT + constexpr coordinate_facade(const value_type(&values)[rank]) _NOEXCEPT { static_assert(std::is_base_of::value, "ConcreteType must be derived from coordinate_facade."); for (size_t i = 0; i < rank; ++i) elems[i] = values[i]; } - _CONSTEXPR coordinate_facade(value_type e0) _NOEXCEPT + constexpr coordinate_facade(value_type e0) _NOEXCEPT { static_assert(std::is_base_of::value, "ConcreteType must be derived from coordinate_facade."); static_assert(rank == 1, "This constructor can only be used with rank == 1."); elems[0] = e0; } // Preconditions: il.size() == rank - _CONSTEXPR coordinate_facade(std::initializer_list il) + constexpr coordinate_facade(std::initializer_list il) { static_assert(std::is_base_of::value, "ConcreteType must be derived from coordinate_facade."); fail_fast_assert(il.size() == rank, "The size of the initializer list must match the rank of the array"); @@ -115,10 +114,10 @@ namespace details } } - _CONSTEXPR coordinate_facade(const coordinate_facade & other) = default; + constexpr coordinate_facade(const coordinate_facade & other) = default; template - _CONSTEXPR coordinate_facade(const coordinate_facade & other) + constexpr coordinate_facade(const coordinate_facade & other) { for (size_t i = 0; i < rank; ++i) { @@ -129,18 +128,18 @@ namespace details protected: coordinate_facade& operator=(const coordinate_facade& rhs) = default; // Preconditions: component_idx < rank - _CONSTEXPR reference operator[](size_t component_idx) + constexpr reference operator[](size_t component_idx) { fail_fast_assert(component_idx < rank, "Component index must be less than rank"); return elems[component_idx]; } // Preconditions: component_idx < rank - _CONSTEXPR const_reference operator[](size_t component_idx) const + constexpr const_reference operator[](size_t component_idx) const { fail_fast_assert(component_idx < rank, "Component index must be less than rank"); return elems[component_idx]; } - _CONSTEXPR bool operator==(const ConcreteType& rhs) const _NOEXCEPT + constexpr bool operator==(const ConcreteType& rhs) const _NOEXCEPT { for (size_t i = 0; i < rank; ++i) { @@ -149,94 +148,94 @@ namespace details } return true; } - _CONSTEXPR bool operator!=(const ConcreteType& rhs) const _NOEXCEPT + constexpr bool operator!=(const ConcreteType& rhs) const _NOEXCEPT { return !(to_concrete() == rhs); } - _CONSTEXPR ConcreteType operator+() const _NOEXCEPT + constexpr ConcreteType operator+() const _NOEXCEPT { return to_concrete(); } - _CONSTEXPR ConcreteType operator-() const + constexpr ConcreteType operator-() const { ConcreteType ret = to_concrete(); for (size_t i = 0; i < rank; ++i) ret.elems[i] = -ret.elems[i]; return ret; } - _CONSTEXPR ConcreteType operator+(const ConcreteType& rhs) const + constexpr ConcreteType operator+(const ConcreteType& rhs) const { ConcreteType ret = to_concrete(); ret += rhs; return ret; } - _CONSTEXPR ConcreteType operator-(const ConcreteType& rhs) const + constexpr ConcreteType operator-(const ConcreteType& rhs) const { ConcreteType ret = to_concrete(); ret -= rhs; return ret; } - _CONSTEXPR ConcreteType& operator+=(const ConcreteType& rhs) + constexpr ConcreteType& operator+=(const ConcreteType& rhs) { for (size_t i = 0; i < rank; ++i) elems[i] += rhs.elems[i]; return to_concrete(); } - _CONSTEXPR ConcreteType& operator-=(const ConcreteType& rhs) + constexpr ConcreteType& operator-=(const ConcreteType& rhs) { for (size_t i = 0; i < rank; ++i) elems[i] -= rhs.elems[i]; return to_concrete(); } - _CONSTEXPR ConcreteType& operator++() + constexpr ConcreteType& operator++() { static_assert(rank == 1, "This operator can only be used with rank == 1."); ++elems[0]; return to_concrete(); } - _CONSTEXPR ConcreteType operator++(int) + constexpr ConcreteType operator++(int) { static_assert(rank == 1, "This operator can only be used with rank == 1."); ConcreteType ret = to_concrete(); ++(*this); return ret; } - _CONSTEXPR ConcreteType& operator--() + constexpr ConcreteType& operator--() { static_assert(rank == 1, "This operator can only be used with rank == 1."); --elems[0]; return to_concrete(); } - _CONSTEXPR ConcreteType operator--(int) + constexpr ConcreteType operator--(int) { static_assert(rank == 1, "This operator can only be used with rank == 1."); ConcreteType ret = to_concrete(); --(*this); return ret; } - _CONSTEXPR ConcreteType operator*(value_type v) const + constexpr ConcreteType operator*(value_type v) const { ConcreteType ret = to_concrete(); ret *= v; return ret; } - _CONSTEXPR ConcreteType operator/(value_type v) const + constexpr ConcreteType operator/(value_type v) const { ConcreteType ret = to_concrete(); ret /= v; return ret; } - friend _CONSTEXPR ConcreteType operator*(value_type v, const ConcreteType& rhs) + friend constexpr ConcreteType operator*(value_type v, const ConcreteType& rhs) { return rhs * v; } - _CONSTEXPR ConcreteType& operator*=(value_type v) + constexpr ConcreteType& operator*=(value_type v) { for (size_t i = 0; i < rank; ++i) elems[i] *= v; return to_concrete(); } - _CONSTEXPR ConcreteType& operator/=(value_type v) + constexpr ConcreteType& operator/=(value_type v) { for (size_t i = 0; i < rank; ++i) elems[i] /= v; @@ -244,11 +243,11 @@ namespace details } value_type elems[rank] = {}; private: - _CONSTEXPR const ConcreteType& to_concrete() const _NOEXCEPT + constexpr const ConcreteType& to_concrete() const _NOEXCEPT { return static_cast(*this); } - _CONSTEXPR ConcreteType& to_concrete() _NOEXCEPT + constexpr ConcreteType& to_concrete() _NOEXCEPT { return static_cast(*this); } @@ -286,17 +285,17 @@ public: using const_reference = typename Base::const_reference; using size_type = typename Base::value_type; using value_type = typename Base::value_type; - _CONSTEXPR index() _NOEXCEPT : Base(){} - _CONSTEXPR index(const value_type (&values)[rank]) _NOEXCEPT : Base(values) {} - _CONSTEXPR index(std::initializer_list il) : Base(il) {} + constexpr index() _NOEXCEPT : Base(){} + constexpr index(const value_type (&values)[rank]) _NOEXCEPT : Base(values) {} + constexpr index(std::initializer_list il) : Base(il) {} - _CONSTEXPR index(const index &) = default; + constexpr index(const index &) = default; template - _CONSTEXPR index(const index &other) : Base(other) + constexpr index(const index &other) : Base(other) { } - _CONSTEXPR static index shift_left(const index& other) _NOEXCEPT + constexpr static index shift_left(const index& other) _NOEXCEPT { value_type (&arr)[rank] = (value_type(&)[rank])(*(other.elems + 1)); return index(arr); @@ -329,124 +328,124 @@ public: using size_type = ValueType; using value_type = ValueType; - _CONSTEXPR index() _NOEXCEPT : value(0) + constexpr index() _NOEXCEPT : value(0) { } - _CONSTEXPR index(value_type e0) _NOEXCEPT : value(e0) + constexpr index(value_type e0) _NOEXCEPT : value(e0) { } - _CONSTEXPR index(const value_type(&values)[1]) _NOEXCEPT : index(values[0]) + constexpr index(const value_type(&values)[1]) _NOEXCEPT : index(values[0]) { } // Preconditions: il.size() == rank - _CONSTEXPR index(std::initializer_list il) + constexpr index(std::initializer_list il) { fail_fast_assert(il.size() == rank, "Size of the initializer list must match the rank of the array"); value = begin(il)[0]; } - _CONSTEXPR index(const index &) = default; + constexpr index(const index &) = default; template - _CONSTEXPR index(const index<1, OtherValueType> & other) + constexpr index(const index<1, OtherValueType> & other) { fail_fast_assert(other.value <= details::SizeTypeTraits::max_value); value = static_cast(other.value); } - _CONSTEXPR static index shift_left(const index& other) _NOEXCEPT + constexpr static index shift_left(const index& other) _NOEXCEPT { return other.elems[1]; } // Preconditions: component_idx < rank - _CONSTEXPR reference operator[](size_type component_idx) _NOEXCEPT + constexpr reference operator[](size_type component_idx) _NOEXCEPT { fail_fast_assert(component_idx == 0, "Component index must be less than rank"); (void)(component_idx); return value; } // Preconditions: component_idx < rank - _CONSTEXPR const_reference operator[](size_type component_idx) const _NOEXCEPT + constexpr const_reference operator[](size_type component_idx) const _NOEXCEPT { fail_fast_assert(component_idx == 0, "Component index must be less than rank"); (void)(component_idx); return value; } - _CONSTEXPR bool operator==(const index& rhs) const _NOEXCEPT + constexpr bool operator==(const index& rhs) const _NOEXCEPT { return value == rhs.value; } - _CONSTEXPR bool operator!=(const index& rhs) const _NOEXCEPT + constexpr bool operator!=(const index& rhs) const _NOEXCEPT { return !(*this == rhs); } - _CONSTEXPR index operator+() const _NOEXCEPT + constexpr index operator+() const _NOEXCEPT { return *this; } - _CONSTEXPR index operator-() const _NOEXCEPT + constexpr index operator-() const _NOEXCEPT { return index(-value); } - _CONSTEXPR index operator+(const index& rhs) const _NOEXCEPT + constexpr index operator+(const index& rhs) const _NOEXCEPT { return index(value + rhs.value); } - _CONSTEXPR index operator-(const index& rhs) const _NOEXCEPT + constexpr index operator-(const index& rhs) const _NOEXCEPT { return index(value - rhs.value); } - _CONSTEXPR index& operator+=(const index& rhs) _NOEXCEPT + constexpr index& operator+=(const index& rhs) _NOEXCEPT { value += rhs.value; return *this; } - _CONSTEXPR index& operator-=(const index& rhs) _NOEXCEPT + constexpr index& operator-=(const index& rhs) _NOEXCEPT { value -= rhs.value; return *this; } - _CONSTEXPR index& operator++() _NOEXCEPT + constexpr index& operator++() _NOEXCEPT { ++value; return *this; } - _CONSTEXPR index operator++(int) _NOEXCEPT + constexpr index operator++(int) _NOEXCEPT { index ret = *this; ++(*this); return ret; } - _CONSTEXPR index& operator--() _NOEXCEPT + constexpr index& operator--() _NOEXCEPT { --value; return *this; } - _CONSTEXPR index operator--(int) _NOEXCEPT + constexpr index operator--(int) _NOEXCEPT { index ret = *this; --(*this); return ret; } - _CONSTEXPR index operator*(value_type v) const _NOEXCEPT + constexpr index operator*(value_type v) const _NOEXCEPT { return index(value * v); } - _CONSTEXPR index operator/(value_type v) const _NOEXCEPT + constexpr index operator/(value_type v) const _NOEXCEPT { return index(value / v); } - _CONSTEXPR index& operator*=(value_type v) _NOEXCEPT + constexpr index& operator*=(value_type v) _NOEXCEPT { value *= v; return *this; } - _CONSTEXPR index& operator/=(value_type v) _NOEXCEPT + constexpr index& operator/=(value_type v) _NOEXCEPT { value /= v; return *this; } - friend _CONSTEXPR index operator*(value_type v, const index& rhs) _NOEXCEPT + friend constexpr index operator*(value_type v, const index& rhs) _NOEXCEPT { return index(rhs * v); } @@ -777,7 +776,7 @@ class static_bounds && details::SizeTypeTraits::max_value <= SIZE_MAX, "SizeType must be an integral type and its numeric limits must be smaller than SIZE_MAX"); MyRanges m_ranges; - _CONSTEXPR static_bounds(const MyRanges & range) : m_ranges(range) { } + constexpr static_bounds(const MyRanges & range) : m_ranges(range) { } template friend class static_bounds; @@ -794,72 +793,72 @@ public: using sliced_type = static_bounds; using mapping_type = contiguous_mapping_tag; public: - _CONSTEXPR static_bounds(const static_bounds &) = default; + constexpr static_bounds(const static_bounds &) = default; template , details::BoundsRanges >::value>> - _CONSTEXPR static_bounds(const static_bounds &other): + constexpr static_bounds(const static_bounds &other): m_ranges(other.m_ranges) { } - _CONSTEXPR static_bounds(std::initializer_list il) : m_ranges(il.begin()) + constexpr static_bounds(std::initializer_list il) : m_ranges(il.begin()) { fail_fast_assert(MyRanges::DynamicNum == il.size(), "Size of the initializer list must match the rank of the array"); fail_fast_assert(m_ranges.totalSize() <= details::SizeTypeTraits::max_value, "Size of the range is larger than the max element of the size type"); } - _CONSTEXPR static_bounds() = default; + constexpr static_bounds() = default; - _CONSTEXPR static_bounds & operator = (const static_bounds & otherBounds) + constexpr static_bounds & operator = (const static_bounds & otherBounds) { new(&m_ranges) MyRanges (otherBounds.m_ranges); return *this; } - _CONSTEXPR sliced_type slice() const _NOEXCEPT + constexpr sliced_type slice() const _NOEXCEPT { return sliced_type{static_cast &>(m_ranges)}; } - _CONSTEXPR size_type stride() const _NOEXCEPT + constexpr size_type stride() const _NOEXCEPT { return rank > 1 ? slice().size() : 1; } - _CONSTEXPR size_type size() const _NOEXCEPT + constexpr size_type size() const _NOEXCEPT { return static_cast(m_ranges.totalSize()); } - _CONSTEXPR size_type total_size() const _NOEXCEPT + constexpr size_type total_size() const _NOEXCEPT { return static_cast(m_ranges.totalSize()); } - _CONSTEXPR size_type linearize(const index_type & idx) const + constexpr size_type linearize(const index_type & idx) const { return m_ranges.linearize(idx); } - _CONSTEXPR bool contains(const index_type& idx) const _NOEXCEPT + constexpr bool contains(const index_type& idx) const _NOEXCEPT { return m_ranges.contains(idx) != -1; } - _CONSTEXPR size_type operator[](size_t index) const _NOEXCEPT + constexpr size_type operator[](size_t index) const _NOEXCEPT { return m_ranges.elementNum(index); } template - _CONSTEXPR size_type extent() const _NOEXCEPT + constexpr size_type extent() const _NOEXCEPT { static_assert(Dim < rank, "dimension should be less than rank (dimension count starts from 0)"); return details::createTypeListIndexer(m_ranges).template get().elementNum(); } - _CONSTEXPR index_type index_bounds() const _NOEXCEPT + constexpr index_type index_bounds() const _NOEXCEPT { index_type extents; m_ranges.serialize(extents); @@ -867,23 +866,23 @@ public: } template - _CONSTEXPR bool operator == (const static_bounds & rhs) const _NOEXCEPT + constexpr bool operator == (const static_bounds & rhs) const _NOEXCEPT { return this->size() == rhs.size(); } template - _CONSTEXPR bool operator != (const static_bounds & rhs) const _NOEXCEPT + constexpr bool operator != (const static_bounds & rhs) const _NOEXCEPT { return !(*this == rhs); } - _CONSTEXPR const_iterator begin() const _NOEXCEPT + constexpr const_iterator begin() const _NOEXCEPT { return const_iterator(*this); } - _CONSTEXPR const_iterator end() const _NOEXCEPT + constexpr const_iterator end() const _NOEXCEPT { index_type boundary; m_ranges.serialize(boundary); @@ -913,43 +912,43 @@ public: static const size_t static_size = dynamic_range; using sliced_type = std::conditional_t, void>; using mapping_type = generalized_mapping_tag; - _CONSTEXPR strided_bounds(const strided_bounds &) = default; + constexpr strided_bounds(const strided_bounds &) = default; template - _CONSTEXPR strided_bounds(const strided_bounds &other) + constexpr strided_bounds(const strided_bounds &other) : Base(other), m_strides(other.strides) { } - _CONSTEXPR strided_bounds(const index_type &extents, const index_type &strides) + constexpr strided_bounds(const index_type &extents, const index_type &strides) : m_strides(strides) { for (size_t i = 0; i < rank; i++) Base::elems[i] = extents[i]; } - _CONSTEXPR strided_bounds(const value_type(&values)[rank], index_type strides) + constexpr strided_bounds(const value_type(&values)[rank], index_type strides) : Base(values), m_strides(std::move(strides)) { } - _CONSTEXPR index_type strides() const _NOEXCEPT + constexpr index_type strides() const _NOEXCEPT { return m_strides; } - _CONSTEXPR size_type total_size() const _NOEXCEPT + constexpr size_type total_size() const _NOEXCEPT { size_type ret = 0; for (size_t i = 0; i < rank; ++i) ret += (Base::elems[i] - 1) * m_strides[i]; return ret + 1; } - _CONSTEXPR size_type size() const _NOEXCEPT + constexpr size_type size() const _NOEXCEPT { size_type ret = 1; for (size_t i = 0; i < rank; ++i) ret *= Base::elems[i]; return ret; } - _CONSTEXPR bool contains(const index_type& idx) const _NOEXCEPT + constexpr bool contains(const index_type& idx) const _NOEXCEPT { for (size_t i = 0; i < rank; ++i) { @@ -958,7 +957,7 @@ public: } return true; } - _CONSTEXPR size_type linearize(const index_type & idx) const + constexpr size_type linearize(const index_type & idx) const { size_type ret = 0; for (size_t i = 0; i < rank; i++) @@ -968,22 +967,22 @@ public: } return ret; } - _CONSTEXPR size_type stride() const _NOEXCEPT + constexpr size_type stride() const _NOEXCEPT { return m_strides[0]; } template 1), typename Ret = std::enable_if_t> - _CONSTEXPR sliced_type slice() const + constexpr sliced_type slice() const { return{ (value_type(&)[rank - 1])Base::elems[1], sliced_type::index_type::shift_left(m_strides) }; } template - _CONSTEXPR size_type extent() const _NOEXCEPT + constexpr size_type extent() const _NOEXCEPT { static_assert(Dim < Rank, "dimension should be less than rank (dimension count starts from 0)"); return Base::elems[Dim]; } - _CONSTEXPR index_type index_bounds() const _NOEXCEPT + constexpr index_type index_bounds() const _NOEXCEPT { return index_type(Base::elems); } @@ -1323,14 +1322,14 @@ bounds_iterator operator+(typename bounds_iterator::differ namespace details { template - _CONSTEXPR std::enable_if_t::value, typename Bounds::index_type> make_stride(const Bounds& bnd) _NOEXCEPT + constexpr std::enable_if_t::value, typename Bounds::index_type> make_stride(const Bounds& bnd) _NOEXCEPT { return bnd.strides(); } // Make a stride vector from bounds, assuming contiguous memory. template - _CONSTEXPR std::enable_if_t::value, typename Bounds::index_type> make_stride(const Bounds& bnd) _NOEXCEPT + constexpr std::enable_if_t::value, typename Bounds::index_type> make_stride(const Bounds& bnd) _NOEXCEPT { auto extents = bnd.index_bounds(); typename Bounds::index_type stride; @@ -1380,30 +1379,30 @@ private: bounds_type m_bounds; public: - _CONSTEXPR bounds_type bounds() const _NOEXCEPT + constexpr bounds_type bounds() const _NOEXCEPT { return m_bounds; } template - _CONSTEXPR size_type extent() const _NOEXCEPT + constexpr size_type extent() const _NOEXCEPT { static_assert(Dim < rank, "dimension should be less than rank (dimension count starts from 0)"); return m_bounds.template extent(); } - _CONSTEXPR size_type size() const _NOEXCEPT + constexpr size_type size() const _NOEXCEPT { return m_bounds.size(); } - _CONSTEXPR reference operator[](const index_type& idx) const + constexpr reference operator[](const index_type& idx) const { return m_pdata[m_bounds.linearize(idx)]; } - _CONSTEXPR pointer data() const _NOEXCEPT + constexpr pointer data() const _NOEXCEPT { return m_pdata; } template 1), typename Ret = std::enable_if_t> - _CONSTEXPR Ret operator[](size_type idx) const + constexpr Ret operator[](size_type idx) const { fail_fast_assert(idx < m_bounds.size(), "index is out of bounds of the array"); const size_type ridx = idx * m_bounds.stride(); @@ -1412,78 +1411,78 @@ public: return Ret {m_pdata + ridx, m_bounds.slice()}; } - _CONSTEXPR operator bool () const _NOEXCEPT + constexpr operator bool () const _NOEXCEPT { return m_pdata != nullptr; } - _CONSTEXPR iterator begin() const + constexpr iterator begin() const { return iterator {this, true}; } - _CONSTEXPR iterator end() const + constexpr iterator end() const { return iterator {this}; } - _CONSTEXPR const_iterator cbegin() const + constexpr const_iterator cbegin() const { return const_iterator {reinterpret_cast *>(this), true}; } - _CONSTEXPR const_iterator cend() const + constexpr const_iterator cend() const { return const_iterator {reinterpret_cast *>(this)}; } - _CONSTEXPR reverse_iterator rbegin() const + constexpr reverse_iterator rbegin() const { return reverse_iterator {end()}; } - _CONSTEXPR reverse_iterator rend() const + constexpr reverse_iterator rend() const { return reverse_iterator {begin()}; } - _CONSTEXPR const_reverse_iterator crbegin() const + constexpr const_reverse_iterator crbegin() const { return const_reverse_iterator {cend()}; } - _CONSTEXPR const_reverse_iterator crend() const + constexpr const_reverse_iterator crend() const { return const_reverse_iterator {cbegin()}; } template , std::remove_cv_t>::value>> - _CONSTEXPR bool operator== (const basic_array_view & other) const _NOEXCEPT + constexpr bool operator== (const basic_array_view & other) const _NOEXCEPT { return m_bounds.size() == other.m_bounds.size() && (m_pdata == other.m_pdata || std::equal(this->begin(), this->end(), other.begin())); } template , std::remove_cv_t>::value>> - _CONSTEXPR bool operator!= (const basic_array_view & other) const _NOEXCEPT + constexpr bool operator!= (const basic_array_view & other) const _NOEXCEPT { return !(*this == other); } template , std::remove_cv_t>::value>> - _CONSTEXPR bool operator< (const basic_array_view & other) const _NOEXCEPT + constexpr bool operator< (const basic_array_view & other) const _NOEXCEPT { return std::lexicographical_compare(this->begin(), this->end(), other.begin(), other.end()); } template , std::remove_cv_t>::value>> - _CONSTEXPR bool operator<= (const basic_array_view & other) const _NOEXCEPT + constexpr bool operator<= (const basic_array_view & other) const _NOEXCEPT { return !(other < *this); } template , std::remove_cv_t>::value>> - _CONSTEXPR bool operator> (const basic_array_view & other) const _NOEXCEPT + constexpr bool operator> (const basic_array_view & other) const _NOEXCEPT { return (other < *this); } template , std::remove_cv_t>::value>> - _CONSTEXPR bool operator>= (const basic_array_view & other) const _NOEXCEPT + constexpr bool operator>= (const basic_array_view & other) const _NOEXCEPT { return !(*this < other); } @@ -1492,27 +1491,27 @@ public: template ::value && std::is_convertible::value>> - _CONSTEXPR basic_array_view(const basic_array_view & other ) _NOEXCEPT + constexpr basic_array_view(const basic_array_view & other ) _NOEXCEPT : m_pdata(other.m_pdata), m_bounds(other.m_bounds) { } protected: - _CONSTEXPR basic_array_view(pointer data, bounds_type bound) _NOEXCEPT + constexpr basic_array_view(pointer data, bounds_type bound) _NOEXCEPT : m_pdata(data) , m_bounds(std::move(bound)) { fail_fast_assert((m_bounds.size() > 0 && data != nullptr) || m_bounds.size() == 0); } template - _CONSTEXPR basic_array_view(T *data, std::enable_if_t>::value, bounds_type> bound) _NOEXCEPT + constexpr basic_array_view(T *data, std::enable_if_t>::value, bounds_type> bound) _NOEXCEPT : m_pdata(reinterpret_cast(data)) , m_bounds(std::move(bound)) { fail_fast_assert((m_bounds.size() > 0 && data != nullptr) || m_bounds.size() == 0); } template - _CONSTEXPR basic_array_view as_array_view(const DestBounds &bounds) + constexpr basic_array_view as_array_view(const DestBounds &bounds) { details::verifyBoundsReshape(m_bounds, bounds); return {m_pdata, bounds}; @@ -1661,22 +1660,22 @@ public: public: // basic - _CONSTEXPR array_view(pointer ptr, bounds_type bounds) : Base(ptr, std::move(bounds)) + constexpr array_view(pointer ptr, bounds_type bounds) : Base(ptr, std::move(bounds)) { } - _CONSTEXPR array_view(std::nullptr_t) : Base(nullptr, bounds_type{}) + constexpr array_view(std::nullptr_t) : Base(nullptr, bounds_type{}) { } - _CONSTEXPR array_view(std::nullptr_t, size_type size) : Base(nullptr, bounds_type{}) + constexpr array_view(std::nullptr_t, size_type size) : Base(nullptr, bounds_type{}) { fail_fast_assert(size == 0); } // default template > - _CONSTEXPR array_view() : Base(nullptr, bounds_type()) + constexpr array_view() : Base(nullptr, bounds_type()) { } @@ -1684,7 +1683,7 @@ public: template , typename Dummy = std::enable_if_t::value && std::is_convertible::value>> - _CONSTEXPR array_view(T * const & data, size_type size) : Base(data, typename Helper::bounds_type{size}) + constexpr array_view(T * const & data, size_type size) : Base(data, typename Helper::bounds_type{size}) { } @@ -1692,7 +1691,7 @@ public: template , typename Dummy = std::enable_if_t::value && std::is_convertible::value>> - _CONSTEXPR array_view (T (&arr)[N]) : Base(arr, typename Helper::bounds_type()) + constexpr array_view (T (&arr)[N]) : Base(arr, typename Helper::bounds_type()) { } @@ -1700,19 +1699,19 @@ public: template , typename Dummy = std::enable_if_t::value && std::is_convertible::value >> - _CONSTEXPR array_view(T(&arr)[N], size_type size) : Base(arr, typename Helper::bounds_type{ size }) + constexpr array_view(T(&arr)[N], size_type size) : Base(arr, typename Helper::bounds_type{ size }) { fail_fast_assert(size <= N); } // from std array template , typename Base::bounds_type>::value>> - _CONSTEXPR array_view (std::array, N> & arr) : Base(arr.data(), static_bounds()) + constexpr array_view (std::array, N> & arr) : Base(arr.data(), static_bounds()) { } template , typename Base::bounds_type>::value && std::is_const::value>> - _CONSTEXPR array_view (const std::array, N> & arr) : Base(arr.data(), static_bounds()) + constexpr array_view (const std::array, N> & arr) : Base(arr.data(), static_bounds()) { } @@ -1721,7 +1720,7 @@ public: template ::value && details::LessThan::value>> // remove literal 0 case - _CONSTEXPR array_view (pointer begin, Ptr end) : Base(begin, details::newBoundsHelper(static_cast(end) - begin)) + constexpr array_view (pointer begin, Ptr end) : Base(begin, details::newBoundsHelper(static_cast(end) - begin)) { } @@ -1732,12 +1731,12 @@ public: && std::is_convertible, typename Base::bounds_type>::value && std::is_same().size(), *std::declval().data())>, DataType>::value> > - _CONSTEXPR array_view (Cont& cont) : Base(static_cast(cont.data()), details::newBoundsHelper(cont.size())) + constexpr array_view (Cont& cont) : Base(static_cast(cont.data()), details::newBoundsHelper(cont.size())) { } - _CONSTEXPR array_view(const array_view &) = default; + constexpr array_view(const array_view &) = default; // convertible template ::value_type, static_bounds::size_type, OtherDimensions...>>, typename Dummy = std::enable_if_t::value> > - _CONSTEXPR array_view(const array_view &av) : Base(static_cast::Base &>(av)) {} // static_cast is required + constexpr array_view(const array_view &av) : Base(static_cast::Base &>(av)) {} // static_cast is required // reshape template - _CONSTEXPR array_view as_array_view(Dimensions2... dims) + constexpr array_view as_array_view(Dimensions2... dims) { static_assert(sizeof...(Dimensions2) > 0, "the target array_view must have at least one dimension."); using BoundsType = typename array_view::bounds_type; @@ -1760,7 +1759,7 @@ public: // to bytes array template ::value_type>>::value> - _CONSTEXPR auto as_bytes() const _NOEXCEPT -> + constexpr auto as_bytes() const _NOEXCEPT -> array_view, static_cast(details::StaticSizeHelper::value)> { static_assert(Enabled, "The value_type of array_view must be standarded layout"); @@ -1768,7 +1767,7 @@ public: } template ::value_type>>::value> - _CONSTEXPR auto as_writeable_bytes() const _NOEXCEPT -> + constexpr auto as_writeable_bytes() const _NOEXCEPT -> array_view, static_cast(details::StaticSizeHelper::value)> { static_assert(Enabled, "The value_type of array_view must be standarded layout"); @@ -1778,7 +1777,7 @@ public: // from bytes array template::value, typename Dummy = std::enable_if_t> - _CONSTEXPR auto as_array_view() const _NOEXCEPT -> array_view(dynamic_range))> + constexpr auto as_array_view() const _NOEXCEPT -> array_view(dynamic_range))> { static_assert(std::is_standard_layout::value && (Base::bounds_type::static_size == dynamic_range || Base::bounds_type::static_size % sizeof(U) == 0), "Target type must be standard layout and its size must match the byte array size"); @@ -1787,7 +1786,7 @@ public: } template::value, typename Dummy = std::enable_if_t> - _CONSTEXPR auto as_array_view() const _NOEXCEPT -> array_view(dynamic_range))> + constexpr auto as_array_view() const _NOEXCEPT -> array_view(dynamic_range))> { static_assert(std::is_standard_layout::value && (Base::bounds_type::static_size == dynamic_range || Base::bounds_type::static_size % sizeof(U) == 0), "Target type must be standard layout and its size must match the byte array size"); @@ -1797,79 +1796,79 @@ public: // section on linear space template - _CONSTEXPR array_view first() const _NOEXCEPT + constexpr array_view first() const _NOEXCEPT { static_assert(bounds_type::static_size == dynamic_range || Count <= bounds_type::static_size, "Index is out of bound"); fail_fast_assert(bounds_type::static_size != dynamic_range || Count <= this->size()); // ensures we only check condition when needed return { this->data(), Count }; } - _CONSTEXPR array_view first(size_type count) const _NOEXCEPT + constexpr array_view first(size_type count) const _NOEXCEPT { fail_fast_assert(count <= this->size()); return { this->data(), count }; } template - _CONSTEXPR array_view last() const _NOEXCEPT + constexpr array_view last() const _NOEXCEPT { static_assert(bounds_type::static_size == dynamic_range || Count <= bounds_type::static_size, "Index is out of bound"); fail_fast_assert(bounds_type::static_size != dynamic_range || Count <= this->size()); return { this->data() + this->size() - Count, Count }; } - _CONSTEXPR array_view last(size_type count) const _NOEXCEPT + constexpr array_view last(size_type count) const _NOEXCEPT { fail_fast_assert(count <= this->size()); return { this->data() + this->size() - count, count }; } template - _CONSTEXPR array_view sub() const _NOEXCEPT + constexpr array_view sub() const _NOEXCEPT { static_assert(bounds_type::static_size == dynamic_range || ((Offset == 0 || Offset <= bounds_type::static_size) && Offset + Count <= bounds_type::static_size), "Index is out of bound"); fail_fast_assert(bounds_type::static_size != dynamic_range || ((Offset == 0 || Offset <= this->size()) && Offset + Count <= this->size())); return { this->data() + Offset, Count }; } - _CONSTEXPR array_view sub(size_type offset, size_type count = dynamic_range) const _NOEXCEPT + constexpr array_view sub(size_type offset, size_type count = dynamic_range) const _NOEXCEPT { fail_fast_assert((offset == 0 || offset <= this->size()) && (count == dynamic_range || (offset + count) <= this->size())); return { this->data() + offset, count == dynamic_range ? this->length() - offset : count }; } // size - _CONSTEXPR size_type length() const _NOEXCEPT + constexpr size_type length() const _NOEXCEPT { return this->size(); } - _CONSTEXPR size_type used_length() const _NOEXCEPT + constexpr size_type used_length() const _NOEXCEPT { return length(); } - _CONSTEXPR size_type bytes() const _NOEXCEPT + constexpr size_type bytes() const _NOEXCEPT { return sizeof(value_type) * this->size(); } - _CONSTEXPR size_type used_bytes() const _NOEXCEPT + constexpr size_type used_bytes() const _NOEXCEPT { return bytes(); } // section - _CONSTEXPR strided_array_view section(index_type origin, index_type extents) const + constexpr strided_array_view section(index_type origin, index_type extents) const { size_type size = this->bounds().total_size() - this->bounds().linearize(origin); return{ &this->operator[](origin), size, strided_bounds {extents, details::make_stride(Base::bounds())} }; } - _CONSTEXPR reference operator[](const index_type& idx) const + constexpr reference operator[](const index_type& idx) const { return Base::operator[](idx); } template 1), typename Dummy = std::enable_if_t> - _CONSTEXPR array_view operator[](size_type idx) const + constexpr array_view operator[](size_type idx) const { auto ret = Base::operator[](idx); return{ ret.data(), ret.bounds() }; @@ -1884,53 +1883,53 @@ public: }; template -_CONSTEXPR auto as_array_view(T * const & ptr, dim... args) -> array_view, Dimensions...> +constexpr auto as_array_view(T * const & ptr, dim... args) -> array_view, Dimensions...> { return {reinterpret_cast*>(ptr), details::static_as_array_view_helper>(args..., details::Sep{})}; } template -_CONSTEXPR auto as_array_view (T * arr, size_t len) -> typename details::ArrayViewArrayTraits::type +constexpr auto as_array_view (T * arr, size_t len) -> typename details::ArrayViewArrayTraits::type { return {arr, len}; } template -_CONSTEXPR auto as_array_view (T (&arr)[N]) -> typename details::ArrayViewArrayTraits::type +constexpr auto as_array_view (T (&arr)[N]) -> typename details::ArrayViewArrayTraits::type { return {arr}; } template -_CONSTEXPR array_view as_array_view(const std::array &arr) +constexpr array_view as_array_view(const std::array &arr) { return {arr}; } template -_CONSTEXPR array_view as_array_view(const std::array &&) = delete; +constexpr array_view as_array_view(const std::array &&) = delete; template -_CONSTEXPR array_view as_array_view(std::array &arr) +constexpr array_view as_array_view(std::array &arr) { return {arr}; } template -_CONSTEXPR array_view as_array_view(T *begin, T *end) +constexpr array_view as_array_view(T *begin, T *end) { return {begin, end}; } template -_CONSTEXPR auto as_array_view(Cont &arr) -> std::enable_if_t>::value, +constexpr auto as_array_view(Cont &arr) -> std::enable_if_t>::value, array_view, dynamic_range>> { return {arr.data(), arr.size()}; } template -_CONSTEXPR auto as_array_view(Cont &&arr) -> std::enable_if_t>::value, +constexpr auto as_array_view(Cont &&arr) -> std::enable_if_t>::value, array_view, dynamic_range>> = delete; template @@ -1977,7 +1976,7 @@ public: typename OtherBaseType = basic_array_view::value_type, strided_bounds::size_type>>, typename Dummy = std::enable_if_t::value> > - _CONSTEXPR strided_array_view(const strided_array_view &av): Base(static_cast::Base &>(av)) // static_cast is required + constexpr strided_array_view(const strided_array_view &av): Base(static_cast::Base &>(av)) // static_cast is required { } @@ -1998,13 +1997,13 @@ public: return { &this->operator[](origin), size, bounds_type {extents, details::make_stride(Base::bounds())}}; } - _CONSTEXPR reference operator[](const index_type& idx) const + constexpr reference operator[](const index_type& idx) const { return Base::operator[](idx); } template 1), typename Dummy = std::enable_if_t> - _CONSTEXPR strided_array_view operator[](size_type idx) const + constexpr strided_array_view operator[](size_type idx) const { auto ret = Base::operator[](idx); return{ ret.data(), ret.bounds().total_size(), ret.bounds() }; @@ -2282,6 +2281,11 @@ general_array_view_iterator operator+(typename general_array_view_ite } // namespace Guide +#if defined(_MSC_VER) +#undef constexpr +#pragma pop_macro("constexpr") +#endif + #if defined(_MSC_VER) && _MSC_VER <= 1800 #pragma warning(pop) #endif // _MSC_VER <= 1800 From 3402b92ef67571688e927b96c67f2ed7b79e97dc Mon Sep 17 00:00:00 2001 From: Kosov Eugene Date: Mon, 28 Sep 2015 21:20:02 +0300 Subject: [PATCH 11/11] fix clang -Wunused-parameter warnings --- include/array_view.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/array_view.h b/include/array_view.h index 8bfdc69..ca4f897 100644 --- a/include/array_view.h +++ b/include/array_view.h @@ -548,7 +548,7 @@ namespace details // TODO : following signature is for work around VS bug template - BoundsRanges (const OtherType &, bool firstLevel) {} + BoundsRanges (const OtherType &, bool /* firstLevel */) {} BoundsRanges(const SizeType * const) { } BoundsRanges() = default; @@ -593,7 +593,7 @@ namespace details BoundsRanges() : m_bound(0) {} template - BoundsRanges(const BoundsRanges &other, bool firstLevel = true) : + BoundsRanges(const BoundsRanges &other, bool /* firstLevel */ = true) : Base(static_cast&>(other), false), m_bound (static_cast(other.totalSize())) { } @@ -764,7 +764,7 @@ class bounds_iterator; template class static_bounds { public: - static_bounds(const details::BoundsRanges &empty) { + static_bounds(const details::BoundsRanges &) { } }; @@ -2021,7 +2021,7 @@ private: } template > - static index_type resize_stride(const index_type& strides, size_t d, void *p = 0) + static index_type resize_stride(const index_type& strides, size_t , void * = 0) { fail_fast_assert(strides[rank - 1] == 1, "Only strided arrays with regular strides can be resized");