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. diff --git a/include/array_view.h b/include/array_view.h index ac29dcc..bbc4fff 100644 --- a/include/array_view.h +++ b/include/array_view.h @@ -30,17 +30,16 @@ #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") #ifndef _NOEXCEPT -#ifdef SAFER_CPP_TESTING +#ifdef GSL_THROWS_FOR_TESTING #define _NOEXCEPT #else #define _NOEXCEPT noexcept @@ -48,7 +47,7 @@ #else // _NOEXCEPT -#ifdef SAFER_CPP_TESTING +#ifdef GSL_THROWS_FOR_TESTING #undef _NOEXCEPT #define _NOEXCEPT #endif @@ -60,7 +59,7 @@ #pragma warning(disable: 4351) // warns about newly introduced aggregate initializer behavior #endif // _MSC_VER <= 1800 -namespace Guide { +namespace gsl { /* ** begin definitions of index and bounds @@ -78,7 +77,7 @@ namespace details class coordinate_facade { static_assert(std::is_integral::value - && sizeof(ValueType) <= sizeof(size_t), "ValueType must be unsigned integral type!"); + && sizeof(ValueType) <= sizeof(size_t), "ValueType must be an integral type!"); static_assert(Rank > 0, "Rank must be greater than 0!"); template @@ -88,24 +87,24 @@ namespace details using reference = std::add_lvalue_reference_t; using const_reference = std::add_lvalue_reference_t>; 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 const_reference = std::add_lvalue_reference_t>; using size_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); } @@ -549,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; @@ -594,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())) { } @@ -765,7 +764,7 @@ class bounds_iterator; template class static_bounds { public: - static_bounds(const details::BoundsRanges &empty) { + static_bounds(const details::BoundsRanges &) { } }; @@ -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() }; @@ -2022,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"); @@ -2280,7 +2279,12 @@ general_array_view_iterator operator+(typename general_array_view_ite return rhs + n; } -} // namespace Guide +} // namespace gsl + +#if defined(_MSC_VER) +#undef constexpr +#pragma pop_macro("constexpr") +#endif #if defined(_MSC_VER) && _MSC_VER <= 1800 #pragma warning(pop) diff --git a/include/fail_fast.h b/include/fail_fast.h index 78a5102..477bace 100644 --- a/include/fail_fast.h +++ b/include/fail_fast.h @@ -22,14 +22,14 @@ #include #include -namespace Guide +namespace gsl { // // Having "fail fast" result in an exception makes unit testing // the GSL classes that rely upon it much simpler. // -#if defined(SAFER_CPP_TESTING) +#if defined(GSL_THROWS_FOR_TESTING) struct fail_fast : public std::runtime_error { @@ -45,7 +45,7 @@ inline void fail_fast_assert(bool cond, const char* const message) { if (!cond) inline void fail_fast_assert(bool cond) { if (!cond) std::terminate(); } inline void fail_fast_assert(bool cond, const char* const) { if (!cond) std::terminate(); } -#endif // SAFER_CPP_TESTING +#endif // GSL_THROWS_FOR_TESTING } diff --git a/include/gsl.h b/include/gsl.h index fed3b6c..5ae4df6 100644 --- a/include/gsl.h +++ b/include/gsl.h @@ -23,7 +23,7 @@ #include "string_view.h" // zstring, string_view, zstring_builder... #include -namespace Guide +namespace gsl { // @@ -38,8 +38,8 @@ using owner = T; // // GSL.assert: assertions // -#define Expects(x) Guide::fail_fast_assert((x)) -#define Ensures(x) Guide::fail_fast_assert((x)) +#define Expects(x) gsl::fail_fast_assert((x)) +#define Ensures(x) gsl::fail_fast_assert((x)) // // GSL.util: utilities @@ -50,16 +50,17 @@ template class Final_act { public: - explicit Final_act(F f) : f_(std::move(f)) {} - - Final_act(const Final_act&& other) : f_(other.f_) {} + explicit Final_act(F f) : f_(std::move(f)), invoke_(true) {} + + Final_act(Final_act&& other) : f_(std::move(other.f_)), invoke_(true) { other.invoke_ = false; } Final_act(const Final_act&) = delete; Final_act& operator=(const Final_act&) = delete; - - ~Final_act() { f_(); } + + ~Final_act() { if (invoke_) f_(); } private: F f_; + bool invoke_; }; // finally() - convenience function to generate a Final_act @@ -111,21 +112,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 +173,21 @@ private: // // Describes an optional pointer - provides symmetry with not_null // +template +class maybe_null_ret; + template class maybe_null_dbg { + template + friend 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 +198,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,12 +210,51 @@ 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.ptr_), tested_(false) {} + + template ::value>> + maybe_null_dbg& operator=(const maybe_null_dbg &other) + { + ptr_ = other.ptr_; + 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; } bool operator!=(const T& rhs) const { return !(*this == rhs); } - bool operator==(const maybe_null_dbg& rhs) const { tested_ = true; rhs.tested_ = true; return ptr_ == rhs.ptr_; } - bool operator!=(const maybe_null_dbg& rhs) const { return !(*this == rhs); } + template ::value>> + bool operator==(const maybe_null_dbg& rhs) const { tested_ = true; rhs.tested_ = true; return ptr_ == rhs.ptr_; } + template ::value>> + bool operator!=(const maybe_null_dbg& rhs) const { return !(*this == rhs); } T get() const { fail_fast_assert(tested_); @@ -225,8 +268,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 +290,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,12 +349,11 @@ 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_; }; template using maybe_null = maybe_null_ret; -} // namespace Guide +} // namespace gsl #endif // GSL_GSL_H diff --git a/include/string_view.h b/include/string_view.h index 5af480d..ec9132e 100644 --- a/include/string_view.h +++ b/include/string_view.h @@ -22,7 +22,7 @@ #include "array_view.h" #include -namespace Guide +namespace gsl { // // czstring and wzstring @@ -137,7 +137,7 @@ basic_string_view, dynami // to_string() allow (explicit) conversions from string_view to string // template -std::basic_string> to_string(const basic_string_view& view) +std::basic_string> to_string(basic_string_view view) { return{ view.data(), view.length() }; } @@ -164,7 +164,7 @@ public: size_type length() const { return sv_.length(); } pointer assume0() const { return data(); } - string_view_type ensure_z() const { return Guide::ensure_z(sv_); } + string_view_type ensure_z() const { return gsl::ensure_z(sv_); } iterator begin() const { return sv_.begin(); } iterator end() const { return sv_.end(); } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 0415db3..774413f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -9,7 +9,7 @@ include_directories( ./unittest-cpp ) -add_definitions(-DSAFER_CPP_TESTING) +add_definitions(-DGSL_THROWS_FOR_TESTING) if(MSVC14 OR MSVC12) # has the support we need # remove unnecessary warnings about unchecked iterators diff --git a/tests/array_view_tests.cpp b/tests/array_view_tests.cpp index ba251e8..918df9e 100644 --- a/tests/array_view_tests.cpp +++ b/tests/array_view_tests.cpp @@ -27,7 +27,7 @@ using namespace std; -using namespace Guide; +using namespace gsl; namespace { @@ -261,8 +261,8 @@ SUITE(array_view_tests) int a[30][4][5]; auto av = as_array_view(a); - auto sub = av.section({15, 0, 0}, Guide::index<3>{2, 2, 2}); - auto subsub = sub.section({1, 0, 0}, Guide::index<3>{1, 1, 1}); + auto sub = av.section({15, 0, 0}, gsl::index<3>{2, 2, 2}); + auto subsub = sub.section({1, 0, 0}, gsl::index<3>{1, 1, 1}); } TEST(array_view_section) diff --git a/tests/assertion_tests.cpp b/tests/assertion_tests.cpp index 012a043..acd381a 100644 --- a/tests/assertion_tests.cpp +++ b/tests/assertion_tests.cpp @@ -17,7 +17,7 @@ #include #include -using namespace Guide; +using namespace gsl; SUITE(assertion_tests) { diff --git a/tests/at_tests.cpp b/tests/at_tests.cpp index 6a86307..d27dd9d 100644 --- a/tests/at_tests.cpp +++ b/tests/at_tests.cpp @@ -19,7 +19,7 @@ #include using namespace std; -using namespace Guide; +using namespace gsl; SUITE(at_tests) { diff --git a/tests/bounds_tests.cpp b/tests/bounds_tests.cpp index b14a113..c3f549f 100644 --- a/tests/bounds_tests.cpp +++ b/tests/bounds_tests.cpp @@ -19,7 +19,7 @@ #include using namespace std; -using namespace Guide;; +using namespace gsl;; namespace { diff --git a/tests/maybenull_tests.cpp b/tests/maybenull_tests.cpp index 4b74114..74d449f 100644 --- a/tests/maybenull_tests.cpp +++ b/tests/maybenull_tests.cpp @@ -17,8 +17,9 @@ #include #include #include +#include -using namespace Guide; +using namespace gsl; struct MyBase { bool foo() { return true; } }; struct MyDerived : public MyBase {}; @@ -177,13 +178,19 @@ SUITE(MaybeNullTests) maybe_null q = p; CHECK(q == p); + maybe_null_dbg pdbg = &derived; + CHECK(pdbg.present()); + + maybe_null_dbg qdbg = pdbg; + CHECK(qdbg == pdbg); + #ifdef CONFIRM_COMPILATION_ERRORS maybe_null r = p; maybe_null s = reinterpret_cast(p); #endif maybe_null_dbg t = reinterpret_cast(p.get()); - CHECK_THROW((void)(void*)t.get(), fail_fast); + CHECK_THROW((void)(void*)t.get(), fail_fast); maybe_null_dbg u = reinterpret_cast(p.get()); CHECK(u.present()); CHECK((void*)p.get() == (void*)u.get()); @@ -254,6 +261,41 @@ 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); + 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..a9624b8 100644 --- a/tests/notnull_tests.cpp +++ b/tests/notnull_tests.cpp @@ -18,7 +18,7 @@ #include #include -using namespace Guide; +using namespace gsl; struct MyBase {}; struct MyDerived : public MyBase {}; @@ -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 diff --git a/tests/owner_tests.cpp b/tests/owner_tests.cpp index d985533..47c223a 100644 --- a/tests/owner_tests.cpp +++ b/tests/owner_tests.cpp @@ -18,7 +18,7 @@ #include #include -using namespace Guide; +using namespace gsl; SUITE(owner_tests) { diff --git a/tests/string_view_tests.cpp b/tests/string_view_tests.cpp index c382cf0..84b7f3f 100644 --- a/tests/string_view_tests.cpp +++ b/tests/string_view_tests.cpp @@ -20,7 +20,7 @@ #include using namespace std; -using namespace Guide; +using namespace gsl; SUITE(string_view_tests) { diff --git a/tests/utils_tests.cpp b/tests/utils_tests.cpp index 0dc4809..3090c7d 100644 --- a/tests/utils_tests.cpp +++ b/tests/utils_tests.cpp @@ -18,7 +18,7 @@ #include #include -using namespace Guide; +using namespace gsl; SUITE(utils_tests) { @@ -37,6 +37,20 @@ SUITE(utils_tests) CHECK(i == 1); } + TEST(finally_lambda_move) + { + int i = 0; + { + auto _1 = finally([&]() {f(i);}); + { + auto _2 = std::move(_1); + CHECK(i == 0); + } + CHECK(i == 1); + } + CHECK(i == 1); + } + TEST(finally_function_with_bind) { int i = 0;