diff --git a/include/fail_fast.h b/include/fail_fast.h deleted file mode 100644 index b9982eb..0000000 --- a/include/fail_fast.h +++ /dev/null @@ -1,55 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright (c) 2015 Microsoft Corporation. All rights reserved. -// -// This code is licensed under the MIT License (MIT). -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -/////////////////////////////////////////////////////////////////////////////// - -#pragma once - -#ifndef GSL_FAIL_FAST_H -#define GSL_FAIL_FAST_H - -#include - -#if defined(GSL_THROWS_FOR_TESTING) -#include -#endif - -namespace gsl -{ - -// -// Having "fail fast" result in an exception makes unit testing -// the GSL classes that rely upon it much simpler. -// -#if defined(GSL_THROWS_FOR_TESTING) - -struct fail_fast : public std::runtime_error -{ - fail_fast() : std::runtime_error("") {} - explicit fail_fast(char const* const message) : std::runtime_error(message) {} -}; - -inline void fail_fast_assert(bool cond) { if (!cond) throw fail_fast(); } -inline void fail_fast_assert(bool cond, const char* const message) { if (!cond) throw fail_fast(message); } - -#else - -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 // GSL_THROWS_FOR_TESTING - -} - -#endif // GSL_FAIL_FAST_H diff --git a/include/gsl.h b/include/gsl.h index bcaf57a..0575d57 100644 --- a/include/gsl.h +++ b/include/gsl.h @@ -19,6 +19,7 @@ #ifndef GSL_GSL_H #define GSL_GSL_H +#include "gsl_assert.h" // Ensures/Expects #include "span.h" // span, strided_span... #include "string_span.h" // zstring, string_span, zstring_builder... #include @@ -27,15 +28,13 @@ // No MSVC does constexpr fully yet #pragma push_macro("constexpr") -#define constexpr /* nothing */ +#define constexpr // MSVC 2013 workarounds #if _MSC_VER <= 1800 - // noexcept is not understood -#ifndef GSL_THROWS_FOR_TESTING -#define noexcept /* nothing */ -#endif +#pragma push_macro("noexcept") +#define noexcept // turn off some misguided warnings #pragma warning(push) @@ -45,11 +44,6 @@ #endif // _MSC_VER -// In order to test the library, we need it to throw exceptions that we can catch -#ifdef GSL_THROWS_FOR_TESTING -#define noexcept /* nothing */ -#endif // GSL_THROWS_FOR_TESTING - namespace gsl { @@ -63,12 +57,6 @@ using std::shared_ptr; template using owner = T; -// -// GSL.assert: assertions -// -#define Expects(x) gsl::fail_fast_assert((x)) -#define Ensures(x) gsl::fail_fast_assert((x)) - // // GSL.util: utilities // @@ -110,14 +98,14 @@ T narrow(U u) { T t = narrow_cast(u); if (static_cast(t) != u) throw narro // // at() - Bounds-checked way of accessing static arrays, std::array, std::vector // -template -T& at(T(&arr)[N], size_t index) { fail_fast_assert(index < N); return arr[index]; } +template +T& at(T(&arr)[N], size_t index) { Expects(index < N); return arr[index]; } template -T& at(std::array& arr, size_t index) { fail_fast_assert(index < N); return arr[index]; } +T& at(std::array& arr, size_t index) { Expects(index < N); return arr[index]; } template -typename Cont::value_type& at(Cont& cont, size_t index) { fail_fast_assert(index < cont.size()); return cont[index]; } +typename Cont::value_type& at(Cont& cont, size_t index) { Expects(index < cont.size()); return cont[index]; } // @@ -181,7 +169,7 @@ private: // we assume that the compiler can hoist/prove away most of the checks inlined from this function // if not, we could make them optional via conditional compilation - void ensure_invariant() const { fail_fast_assert(ptr_ != nullptr); } + void ensure_invariant() const { Expects(ptr_ != nullptr); } // unwanted operators...pointers only point to single objects! // TODO ensure all arithmetic ops on this type are unavailable @@ -216,18 +204,14 @@ namespace std #pragma pop_macro("constexpr") #if _MSC_VER <= 1800 -#pragma warning(pop) -#ifndef GSL_THROWS_FOR_TESTING #undef noexcept -#endif // GSL_THROWS_FOR_TESTING +#pragma pop_macro("noexcept") + +#pragma warning(pop) #endif // _MSC_VER <= 1800 #endif // _MSC_VER -#if defined(GSL_THROWS_FOR_TESTING) -#undef noexcept -#endif // GSL_THROWS_FOR_TESTING - #endif // GSL_GSL_H diff --git a/include/gsl_assert.h b/include/gsl_assert.h new file mode 100644 index 0000000..4a40552 --- /dev/null +++ b/include/gsl_assert.h @@ -0,0 +1,78 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2015 Microsoft Corporation. All rights reserved. +// +// This code is licensed under the MIT License (MIT). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +/////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#ifndef GSL_CONTRACTS_H +#define GSL_CONTRACTS_H + +#include + +// +// There are three configuration options for this GSL implementation's behavior +// when pre/post conditions on the GSL types are violated: +// +// 1. GSL_TERMINATE_ON_CONTRACT_VIOLATION: std::terminate will be called (default) +// 2. GSL_THROW_ON_CONTRACT_VIOLATION: a gsl::fail_fast exception will be thrown +// 3. GSL_UNENFORCED_ON_CONTRACT_VIOLATION: nothing happens +// +#if !(defined(GSL_THROW_ON_CONTRACT_VIOLATION) ^ defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION) ^ defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION)) +#define GSL_TERMINATE_ON_CONTRACT_VIOLATION +#endif + + +#define GSL_STRINGIFY_DETAIL(x) #x +#define GSL_STRINGIFY(x) GSL_STRINGIFY_DETAIL(x) + + +// +// GSL.assert: assertions +// + +#if defined(GSL_THROW_ON_CONTRACT_VIOLATION) + +#include + +namespace gsl +{ +struct fail_fast : public std::runtime_error +{ + explicit fail_fast(char const* const message) : std::runtime_error(message) {} +}; +} + +#define Expects(cond) if (!(cond)) \ + throw gsl::fail_fast("GSL: Precondition failure at " __FILE__ GSL_STRINGIFY(__LINE__)); +#define Ensures(cond) if (!(cond)) \ + throw gsl::fail_fast("GSL: Postcondition failure at " __FILE__ GSL_STRINGIFY(__LINE__)); + + +#elif defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION) + + +#define Expects(cond) if (!(cond)) std::terminate(); +#define Ensures(cond) if (!(cond)) std::terminate(); + + +#elif defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION) + +#define Expects(cond) +#define Ensures(cond) + +#endif + + +#endif // GSL_CONTRACTS_H diff --git a/include/span.h b/include/span.h index 2bf9d20..0c67d22 100644 --- a/include/span.h +++ b/include/span.h @@ -31,13 +31,18 @@ #include #include #include -#include "fail_fast.h" +#include +#include "gsl_assert.h" #ifdef _MSC_VER +// turn off some warnings that are noisy about our Expects statements +#pragma warning(push) +#pragma warning(disable: 4127) // conditional expression is constant + // No MSVC does constexpr fully yet #pragma push_macro("constexpr") -#define constexpr /* nothing */ +#define constexpr // VS 2013 workarounds #if _MSC_VER <= 1800 @@ -46,7 +51,7 @@ #define GSL_MSVC_HAS_VARIADIC_CTOR_BUG // noexcept is not understood -#ifndef GSL_THROWS_FOR_TESTING +#ifndef GSL_THROWS_ON_CONTRACT_VIOLATION #pragma push_macro("noexcept") #define noexcept /* nothing */ #endif @@ -60,8 +65,7 @@ #endif // _MSC_VER -// In order to test the library, we need it to throw exceptions that we can catch -#ifdef GSL_THROWS_FOR_TESTING +#ifdef GSL_THROW_ON_CONTRACT_VIOLATION #ifdef _MSC_VER #pragma push_macro("noexcept") @@ -69,7 +73,7 @@ #define noexcept /* nothing */ -#endif // GSL_THROWS_FOR_TESTING +#endif // GSL_THROW_ON_CONTRACT_VIOLATION namespace gsl { @@ -137,14 +141,14 @@ public: // Preconditions: component_idx < rank constexpr reference operator[](size_t component_idx) { - fail_fast_assert(component_idx < Rank, "Component index must be less than rank"); + Expects(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 noexcept { - fail_fast_assert(component_idx < Rank, "Component index must be less than rank"); + Expects(component_idx < Rank); // Component index must be less than rank return elems[component_idx]; } @@ -344,7 +348,7 @@ namespace details BoundsRanges(const std::ptrdiff_t* const arr) : Base(arr + 1), m_bound(*arr * this->Base::totalSize()) { - fail_fast_assert(0 <= *arr); + Expects(0 <= *arr); } BoundsRanges() : m_bound(0) {} @@ -365,7 +369,7 @@ namespace details size_type linearize(const T& arr) const { const size_type index = this->Base::totalSize() * arr[Dim]; - fail_fast_assert(index < m_bound); + Expects(index < m_bound); return index + this->Base::template linearize(arr); } @@ -419,8 +423,9 @@ namespace details template BoundsRanges(const BoundsRanges&other, bool firstLevel = true) : Base(static_cast&>(other), false) - { - fail_fast_assert((firstLevel && totalSize() <= other.totalSize()) || totalSize() == other.totalSize()); + { + Expects((firstLevel && totalSize() <= other.totalSize()) || totalSize() == other.totalSize()); + (void)firstLevel; } template @@ -433,7 +438,7 @@ namespace details template size_type linearize(const T& arr) const { - fail_fast_assert(arr[Dim] < CurrentRange, "Index is out of range"); + Expects(arr[Dim] < CurrentRange); // Index is out of range return this->Base::totalSize() * arr[Dim] + this->Base::template linearize(arr); } @@ -584,8 +589,10 @@ public: constexpr static_bounds(std::initializer_list il) : m_ranges((const std::ptrdiff_t*)il.begin()) { - fail_fast_assert((MyRanges::DynamicNum == 0 && il.size() == 1 && *il.begin() == static_size) || MyRanges::DynamicNum == il.size(), "Size of the initializer list must match the rank of the array"); - fail_fast_assert(m_ranges.totalSize() <= PTRDIFF_MAX, "Size of the range is larger than the max element of the size type"); + // Size of the initializer list must match the rank of the array + Expects((MyRanges::DynamicNum == 0 && il.size() == 1 && *il.begin() == static_size) || MyRanges::DynamicNum == il.size()); + // Size of the range must be less than the max element of the size type + Expects(m_ranges.totalSize() <= PTRDIFF_MAX); } constexpr static_bounds() = default; @@ -742,7 +749,7 @@ public: size_type ret = 0; for (size_t i = 0; i < rank; i++) { - fail_fast_assert(idx[i] < m_extents[i], "index is out of bounds of the array"); + Expects(idx[i] < m_extents[i]); // index is out of bounds of the array ret += idx[i] * m_strides[i]; } return ret; @@ -868,7 +875,7 @@ public: } // If we're here the preconditions were violated // "pre: there exists s such that r == ++s" - fail_fast_assert(false); + Expects(false); return *this; } @@ -899,7 +906,8 @@ public: curr[i] = linear_idx / stride[i]; linear_idx = linear_idx % stride[i]; } - fail_fast_assert(!less(curr, index_type{}) && !less(boundary, curr), "index is out of bounds of the array"); + //index is out of bounds of the array + Expects(!less(curr, index_type{}) && !less(boundary, curr)); return *this; } @@ -1038,7 +1046,7 @@ namespace details static_assert(is_bounds::value && is_bounds::value, "The src type and dest type must be bounds"); static_assert(std::is_same::value, "The source type must be a contiguous bounds"); static_assert(BoundsDest::static_size == dynamic_range || BoundsSrc::static_size == dynamic_range || BoundsDest::static_size == BoundsSrc::static_size, "The source bounds must have same size as dest bounds"); - fail_fast_assert(src.size() == dest.size()); + Expects(src.size() == dest.size()); } @@ -1099,13 +1107,13 @@ namespace details template BoundsType newBoundsHelperImpl(std::ptrdiff_t totalSize, std::true_type) // dynamic size { - fail_fast_assert(totalSize <= PTRDIFF_MAX); + Expects(totalSize <= PTRDIFF_MAX); return BoundsType{totalSize}; } template BoundsType newBoundsHelperImpl(std::ptrdiff_t totalSize, std::false_type) // static size { - fail_fast_assert(BoundsType::static_size == totalSize); + Expects(BoundsType::static_size == totalSize); return {}; } template @@ -1192,7 +1200,7 @@ public: constexpr span(pointer data, bounds_type bounds) noexcept : m_pdata(data), m_bounds(std::move(bounds)) { - fail_fast_assert((m_bounds.size() > 0 && data != nullptr) || m_bounds.size() == 0); + Expects((m_bounds.size() > 0 && data != nullptr) || m_bounds.size() == 0); } constexpr span(pointer ptr, size_type size) noexcept @@ -1206,7 +1214,7 @@ public: constexpr span(std::nullptr_t, size_type size) noexcept : span(nullptr, bounds_type{}) { - fail_fast_assert(size == 0); + Expects(size == 0); } // default @@ -1236,7 +1244,7 @@ public: > constexpr span(T(&arr)[N], size_type size) : span(arr, typename Helper::bounds_type{size}) { - fail_fast_assert(size <= N); + Expects(size <= N); } // from std array @@ -1313,7 +1321,7 @@ public: { static_assert(std::is_standard_layout::value && (bounds_type::static_size == dynamic_range || bounds_type::static_size % static_cast(sizeof(U)) == 0), "Target type must be standard layout and its size must match the byte array size"); - fail_fast_assert((this->bytes() % sizeof(U)) == 0 && (this->bytes() / sizeof(U)) < PTRDIFF_MAX); + Expects((this->bytes() % sizeof(U)) == 0 && (this->bytes() / sizeof(U)) < PTRDIFF_MAX); return { reinterpret_cast(this->data()), this->bytes() / static_cast(sizeof(U)) }; } @@ -1322,7 +1330,7 @@ public: { static_assert(std::is_standard_layout::value && (bounds_type::static_size == dynamic_range || bounds_type::static_size % static_cast(sizeof(U)) == 0), "Target type must be standard layout and its size must match the byte array size"); - fail_fast_assert((this->bytes() % sizeof(U)) == 0); + Expects((this->bytes() % sizeof(U)) == 0); return { reinterpret_cast(this->data()), this->bytes() / static_cast(sizeof(U)) }; } @@ -1331,13 +1339,13 @@ public: constexpr span 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 + Expects(bounds_type::static_size != dynamic_range || Count <= this->size()); return { this->data(), Count }; } constexpr span first(size_type count) const noexcept { - fail_fast_assert(count <= this->size()); + Expects(count <= this->size()); return { this->data(), count }; } @@ -1345,13 +1353,13 @@ public: constexpr span 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()); + Expects(bounds_type::static_size != dynamic_range || Count <= this->size()); return { this->data() + this->size() - Count, Count }; } constexpr span last(size_type count) const noexcept { - fail_fast_assert(count <= this->size()); + Expects(count <= this->size()); return { this->data() + this->size() - count, count }; } @@ -1359,13 +1367,13 @@ public: constexpr span 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())); + Expects(bounds_type::static_size != dynamic_range || ((Offset == 0 || Offset <= this->size()) && Offset + Count <= this->size())); return { this->data() + Offset, Count }; } constexpr span 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())); + Expects((offset == 0 || offset <= this->size()) && (count == dynamic_range || (offset + count) <= this->size())); return { this->data() + offset, count == dynamic_range ? this->length() - offset : count }; } @@ -1405,10 +1413,11 @@ public: template 1), typename Ret = std::enable_if_t> constexpr Ret operator[](size_type idx) const noexcept { - fail_fast_assert(idx < m_bounds.size(), "index is out of bounds of the array"); + Expects(idx < m_bounds.size()); // index is out of bounds of the array const size_type ridx = idx * m_bounds.stride(); - fail_fast_assert(ridx < m_bounds.total_size(), "index is out of bounds of the underlying data"); + // index is out of bounds of the underlying data + Expects(ridx < m_bounds.total_size()); return Ret{ m_pdata + ridx, m_bounds.slice() }; } @@ -1560,7 +1569,7 @@ template constexpr auto as_span(Cont &arr) -> std::enable_if_t>::value, span, dynamic_range>> { - fail_fast_assert(arr.size() < PTRDIFF_MAX); + Expects(arr.size() < PTRDIFF_MAX); return {arr.data(), static_cast(arr.size())}; } @@ -1572,7 +1581,7 @@ constexpr auto as_span(Cont &&arr) -> std::enable_if_t constexpr auto as_span(std::basic_string &str) -> span { - fail_fast_assert(str.size() < PTRDIFF_MAX); + Expects(str.size() < PTRDIFF_MAX); return {&str[0], static_cast(str.size())}; } @@ -1608,8 +1617,10 @@ public: constexpr strided_span(pointer ptr, size_type size, bounds_type bounds) : m_pdata(ptr), m_bounds(std::move(bounds)) { - fail_fast_assert((m_bounds.size() > 0 && ptr != nullptr) || m_bounds.size() == 0); - fail_fast_assert(this->bounds().total_size() <= size, "Bounds cross data boundaries"); + Expects((m_bounds.size() > 0 && ptr != nullptr) || m_bounds.size() == 0); + // Bounds cross data boundaries + Expects(this->bounds().total_size() <= size); + (void)size; } // from static array of size N @@ -1659,10 +1670,11 @@ public: template 1), typename Ret = std::enable_if_t> constexpr Ret operator[](size_type idx) const { - fail_fast_assert(idx < m_bounds.size(), "index is out of bounds of the array"); + Expects(idx < m_bounds.size()); // index is out of bounds of the array const size_type ridx = idx * m_bounds.stride(); - fail_fast_assert(ridx < m_bounds.total_size(), "index is out of bounds of the underlying data"); + // index is out of bounds of the underlying data + Expects(ridx < m_bounds.total_size()); return{ m_pdata + ridx, m_bounds.slice().total_size(), m_bounds.slice() }; } @@ -1773,7 +1785,8 @@ public: private: static index_type resize_extent(const index_type& extent, std::ptrdiff_t d) { - fail_fast_assert(extent[Rank - 1] >= d && (extent[Rank-1] % d == 0), "The last dimension of the array needs to contain a multiple of new type elements"); + // The last dimension of the array needs to contain a multiple of new type elements + Expects(extent[Rank - 1] >= d && (extent[Rank - 1] % d == 0)); index_type ret = extent; ret[Rank - 1] /= d; @@ -1784,7 +1797,8 @@ private: template > static index_type resize_stride(const index_type& strides, std::ptrdiff_t , void * = 0) { - fail_fast_assert(strides[Rank - 1] == 1, "Only strided arrays with regular strides can be resized"); + // Only strided arrays with regular strides can be resized + Expects(strides[Rank - 1] == 1); return strides; } @@ -1792,12 +1806,16 @@ private: template 1), typename Dummy = std::enable_if_t> static index_type resize_stride(const index_type& strides, std::ptrdiff_t d) { - 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"); + // Only strided arrays with regular strides can be resized + Expects(strides[Rank - 1] == 1); + // The strides must have contiguous chunks of + // memory that can contain a multiple of new type elements + Expects(strides[Rank - 2] >= d && (strides[Rank - 2] % d == 0)); 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"); + // Only strided arrays with regular strides can be resized + Expects((strides[i - 1] >= strides[i]) && (strides[i - 1] % strides[i] == 0)); } index_type ret = strides / d; @@ -1824,7 +1842,9 @@ private: const Span* m_validator; void validateThis() const { - fail_fast_assert(m_pdata >= m_validator->m_pdata && m_pdata < m_validator->m_pdata + m_validator->size(), "iterator is out of range of the array"); + // iterator is out of range of the array + Expects(m_pdata >= m_validator->m_pdata && + m_pdata < m_validator->m_pdata + m_validator->size()); } contiguous_span_iterator (const Span* container, bool isbegin) : m_pdata(isbegin ? container->m_pdata : container->m_pdata + container->size()), m_validator(container) {} @@ -1882,7 +1902,7 @@ public: } difference_type operator-(const contiguous_span_iterator& rhs) const noexcept { - fail_fast_assert(m_validator == rhs.m_validator); + Expects(m_validator == rhs.m_validator); return m_pdata - rhs.m_pdata; } reference operator[](difference_type n) const noexcept @@ -1891,7 +1911,7 @@ public: } bool operator==(const contiguous_span_iterator& rhs) const noexcept { - fail_fast_assert(m_validator == rhs.m_validator); + Expects(m_validator == rhs.m_validator); return m_pdata == rhs.m_pdata; } bool operator!=(const contiguous_span_iterator& rhs) const noexcept @@ -1900,7 +1920,7 @@ public: } bool operator<(const contiguous_span_iterator& rhs) const noexcept { - fail_fast_assert(m_validator == rhs.m_validator); + Expects(m_validator == rhs.m_validator); return m_pdata < rhs.m_pdata; } bool operator<=(const contiguous_span_iterator& rhs) const noexcept @@ -1998,7 +2018,7 @@ public: } difference_type operator-(const general_span_iterator& rhs) const noexcept { - fail_fast_assert(m_container == rhs.m_container); + Expects(m_container == rhs.m_container); return m_itr - rhs.m_itr; } value_type operator[](difference_type n) const noexcept @@ -2007,7 +2027,7 @@ public: } bool operator==(const general_span_iterator& rhs) const noexcept { - fail_fast_assert(m_container == rhs.m_container); + Expects(m_container == rhs.m_container); return m_itr == rhs.m_itr; } bool operator !=(const general_span_iterator& rhs) const noexcept @@ -2016,7 +2036,7 @@ public: } bool operator<(const general_span_iterator& rhs) const noexcept { - fail_fast_assert(m_container == rhs.m_container); + Expects(m_container == rhs.m_container); return m_itr < rhs.m_itr; } bool operator<=(const general_span_iterator& rhs) const noexcept @@ -2055,10 +2075,10 @@ general_span_iterator operator+(typename general_span_iterator::diff #if _MSC_VER <= 1800 #pragma warning(pop) -#ifndef GSL_THROWS_FOR_TESTING +#ifndef GSL_THROW_ON_CONTRACT_VIOLATION #undef noexcept #pragma pop_macro("noexcept") -#endif // GSL_THROWS_FOR_TESTING +#endif // GSL_THROW_ON_CONTRACT_VIOLATION #undef GSL_MSVC_HAS_VARIADIC_CTOR_BUG @@ -2066,15 +2086,16 @@ general_span_iterator operator+(typename general_span_iterator::diff #endif // _MSC_VER -#if defined(GSL_THROWS_FOR_TESTING) +#if defined(GSL_THROW_ON_CONTRACT_VIOLATION) #undef noexcept #ifdef _MSC_VER +#pragma warning(pop) #pragma pop_macro("noexcept") #endif -#endif // GSL_THROWS_FOR_TESTING +#endif // GSL_THROW_ON_CONTRACT_VIOLATION #endif // GSL_SPAN_H diff --git a/include/string_span.h b/include/string_span.h index b30ebf0..250c528 100644 --- a/include/string_span.h +++ b/include/string_span.h @@ -19,6 +19,7 @@ #ifndef GSL_STRING_SPAN_H #define GSL_STRING_SPAN_H +#include "gsl_assert.h" #include "span.h" #include @@ -89,7 +90,7 @@ span ensure_sentinel(const T* seq, std::ptrdiff_t max = PTRDIF { auto cur = seq; while ((cur - seq) < max && *cur != Sentinel) ++cur; - fail_fast_assert(*cur == Sentinel); + Ensures(*cur == Sentinel); return{ seq, cur - seq }; } @@ -109,26 +110,26 @@ inline basic_string_span ensure_z(T* const & sz, std::ptrdiff_ inline basic_string_span ensure_z(char* const& sz, std::ptrdiff_t max) { auto len = strnlen(sz, max); - fail_fast_assert(sz[len] == 0); + Ensures(sz[len] == 0); return{ sz, static_cast(len) }; } inline basic_string_span ensure_z(const char* const& sz, std::ptrdiff_t max) { auto len = strnlen(sz, max); - fail_fast_assert(sz[len] == 0); return{ sz, static_cast(len) }; + Ensures(sz[len] == 0); return{ sz, static_cast(len) }; } inline basic_string_span ensure_z(wchar_t* const& sz, std::ptrdiff_t max) { auto len = wcsnlen(sz, max); - fail_fast_assert(sz[len] == 0); return{ sz, static_cast(len) }; + Ensures(sz[len] == 0); return{ sz, static_cast(len) }; } inline basic_string_span ensure_z(const wchar_t* const& sz, std::ptrdiff_t max) { auto len = wcsnlen(sz, max); - fail_fast_assert(sz[len] == 0); return{ sz, static_cast(len) }; + Ensures(sz[len] == 0); return{ sz, static_cast(len) }; } template diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5529cda..fe7a831 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -9,7 +9,7 @@ include_directories( ./unittest-cpp ) -add_definitions(-DGSL_THROWS_FOR_TESTING) +add_definitions(-DGSL_THROW_ON_CONTRACT_VIOLATION) if(MSVC14 OR MSVC12) # has the support we need # remove unnecessary warnings about unchecked iterators