diff options
Diffstat (limited to 'include/gsl/string_span')
-rw-r--r-- | include/gsl/string_span | 112 |
1 files changed, 55 insertions, 57 deletions
diff --git a/include/gsl/string_span b/include/gsl/string_span index 2a89561..d298039 100644 --- a/include/gsl/string_span +++ b/include/gsl/string_span @@ -20,6 +20,7 @@ #include <gsl/gsl_assert> // for Ensures, Expects #include <gsl/gsl_util> // for narrow_cast #include <gsl/span> // for operator!=, operator==, dynamic_extent +#include <gsl/pointers> // for not_null #include <algorithm> // for equal, lexicographical_compare #include <array> // for array @@ -32,10 +33,9 @@ #ifdef _MSC_VER #pragma warning(push) -// blanket turn off warnings from CppCoreCheck for now -// so people aren't annoyed by them when running the tool. -// more targeted suppressions will be added in a future update to the GSL -#pragma warning(disable : 26481 26482 26483 26485 26490 26491 26492 26493 26495) +// Turn MSVC /analyze rules that generate too much noise. TODO: fix in the tool. +#pragma warning(disable : 26446) // TODO: bug in parser - attributes and templates +#pragma warning(disable : 26481) // TODO: suppress does not work inside templates sometimes #if _MSC_VER < 1910 #pragma push_macro("constexpr") @@ -98,7 +98,7 @@ namespace details return len; } -} +} // namespace details // // ensure_sentinel() @@ -111,7 +111,13 @@ namespace details template <typename T, const T Sentinel> span<T, dynamic_extent> ensure_sentinel(T* seq, std::ptrdiff_t max = PTRDIFF_MAX) { + Ensures(seq != nullptr); + + GSL_SUPPRESS(f.23) // NO-FORMAT: attribute // TODO: false positive // TODO: suppress does not work auto cur = seq; + Ensures(cur != nullptr); // workaround for removing the warning + + GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute // TODO: suppress does not work while ((cur - seq) < max && *cur != Sentinel) ++cur; Ensures(*cur == Sentinel); return {seq, cur - seq}; @@ -131,21 +137,20 @@ span<CharT, dynamic_extent> ensure_z(CharT* const& sz, std::ptrdiff_t max = PTRD template <typename CharT, std::size_t N> span<CharT, dynamic_extent> ensure_z(CharT (&sz)[N]) { - return ensure_z(&sz[0], static_cast<std::ptrdiff_t>(N)); + return ensure_z(&sz[0], narrow_cast<std::ptrdiff_t>(N)); } template <class Cont> span<typename std::remove_pointer<typename Cont::pointer>::type, dynamic_extent> ensure_z(Cont& cont) { - return ensure_z(cont.data(), static_cast<std::ptrdiff_t>(cont.size())); + return ensure_z(cont.data(), narrow_cast<std::ptrdiff_t>(cont.size())); } template <typename CharT, std::ptrdiff_t> class basic_string_span; -namespace details -{ +namespace details { template <typename T> struct is_basic_string_span_oracle : std::false_type { @@ -160,7 +165,7 @@ namespace details struct is_basic_string_span : is_basic_string_span_oracle<std::remove_cv_t<T>> { }; -} +} // namespace details // // string_span and relatives @@ -197,32 +202,27 @@ public: // All other containers allow 0s within the length, so we do not remove them template <std::size_t N> constexpr basic_string_span(element_type (&arr)[N]) : span_(remove_z(arr)) - { - } + {} template <std::size_t N, class ArrayElementType = std::remove_const_t<element_type>> constexpr basic_string_span(std::array<ArrayElementType, N>& arr) noexcept : span_(arr) - { - } + {} template <std::size_t N, class ArrayElementType = std::remove_const_t<element_type>> - constexpr basic_string_span(const std::array<ArrayElementType, N>& arr) noexcept - : span_(arr) - { - } + constexpr basic_string_span(const std::array<ArrayElementType, N>& arr) noexcept : span_(arr) + {} // Container signature should work for basic_string after C++17 version exists template <class Traits, class Allocator> + // GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute // TODO: parser bug constexpr basic_string_span(std::basic_string<element_type, Traits, Allocator>& str) : span_(&str[0], narrow_cast<std::ptrdiff_t>(str.length())) - { - } + {} template <class Traits, class Allocator> constexpr basic_string_span(const std::basic_string<element_type, Traits, Allocator>& str) : span_(&str[0], str.length()) - { - } + {} // from containers. Containers must have a pointer type and data() function signatures template <class Container, @@ -232,8 +232,7 @@ public: std::is_convertible<typename Container::pointer, decltype(std::declval<Container>().data())>::value>> constexpr basic_string_span(Container& cont) : span_(cont) - { - } + {} template <class Container, class = std::enable_if_t< @@ -242,8 +241,7 @@ public: std::is_convertible<typename Container::pointer, decltype(std::declval<Container>().data())>::value>> constexpr basic_string_span(const Container& cont) : span_(cont) - { - } + {} // from string_span template < @@ -252,8 +250,7 @@ public: typename basic_string_span<OtherValueType, OtherExtent>::impl_type, impl_type>::value>> constexpr basic_string_span(basic_string_span<OtherValueType, OtherExtent> other) : span_(other.data(), other.length()) - { - } + {} template <index_type Count> constexpr basic_string_span<element_type, Count> first() const @@ -359,21 +356,22 @@ template <typename CharT, std::ptrdiff_t Extent> std::basic_string<typename std::remove_const<CharT>::type> to_string(basic_string_span<CharT, Extent> view) { - return {view.data(), static_cast<std::size_t>(view.length())}; + return {view.data(), narrow_cast<std::size_t>(view.length())}; } template <typename CharT, typename Traits = typename std::char_traits<CharT>, typename Allocator = std::allocator<CharT>, typename gCharT, std::ptrdiff_t Extent> std::basic_string<CharT, Traits, Allocator> to_basic_string(basic_string_span<gCharT, Extent> view) { - return {view.data(), static_cast<std::size_t>(view.length())}; + return {view.data(), narrow_cast<std::size_t>(view.length())}; } template <class ElementType, std::ptrdiff_t Extent> basic_string_span<const byte, details::calculate_byte_size<ElementType, Extent>::value> as_bytes(basic_string_span<ElementType, Extent> s) noexcept { - return { reinterpret_cast<const byte*>(s.data()), s.size_bytes() }; + GSL_SUPPRESS(type.1) // NO-FORMAT: attribute + return {reinterpret_cast<const byte*>(s.data()), s.size_bytes()}; } template <class ElementType, std::ptrdiff_t Extent, @@ -381,14 +379,14 @@ template <class ElementType, std::ptrdiff_t Extent, basic_string_span<byte, details::calculate_byte_size<ElementType, Extent>::value> as_writeable_bytes(basic_string_span<ElementType, Extent> s) noexcept { + GSL_SUPPRESS(type.1) // NO-FORMAT: attribute return {reinterpret_cast<byte*>(s.data()), s.size_bytes()}; } // zero-terminated string span, used to convert // zero-terminated spans to legacy strings template <typename CharT, std::ptrdiff_t Extent = dynamic_extent> -class basic_zstring_span -{ +class basic_zstring_span { public: using value_type = CharT; using const_value_type = std::add_const_t<CharT>; @@ -424,10 +422,10 @@ public: constexpr string_span_type as_string_span() const noexcept { - auto sz = span_.size(); - return { span_.data(), sz > 1 ? sz - 1 : 0 }; + const auto sz = span_.size(); + return {span_.data(), sz > 1 ? sz - 1 : 0}; } - constexpr string_span_type ensure_z() const noexcept { return gsl::ensure_z(span_); } + constexpr string_span_type ensure_z() const { return gsl::ensure_z(span_); } constexpr const_zstring_type assume_z() const noexcept { return span_.data(); } @@ -464,7 +462,7 @@ template <class CharT, std::ptrdiff_t Extent, class T, class = std::enable_if_t< details::is_basic_string_span<T>::value || std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>>>::value>> -bool operator==(const gsl::basic_string_span<CharT, Extent>& one, const T& other) noexcept +bool operator==(const gsl::basic_string_span<CharT, Extent>& one, const T& other) { const gsl::basic_string_span<std::add_const_t<CharT>> tmp(other); return std::equal(one.begin(), one.end(), tmp.begin(), tmp.end()); @@ -474,9 +472,9 @@ template <class CharT, std::ptrdiff_t Extent, class T, class = std::enable_if_t< !details::is_basic_string_span<T>::value && std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>>>::value>> -bool operator==(const T& one, const gsl::basic_string_span<CharT, Extent>& other) noexcept +bool operator==(const T& one, const gsl::basic_string_span<CharT, Extent>& other) { - gsl::basic_string_span<std::add_const_t<CharT>> tmp(one); + const gsl::basic_string_span<std::add_const_t<CharT>> tmp(one); return std::equal(tmp.begin(), tmp.end(), other.begin(), other.end()); } @@ -484,7 +482,7 @@ bool operator==(const T& one, const gsl::basic_string_span<CharT, Extent>& other template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T, typename = std::enable_if_t<std::is_convertible< T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>> -bool operator!=(gsl::basic_string_span<CharT, Extent> one, const T& other) noexcept +bool operator!=(gsl::basic_string_span<CharT, Extent> one, const T& other) { return !(one == other); } @@ -494,7 +492,7 @@ template < typename = std::enable_if_t< std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value && !gsl::details::is_basic_string_span<T>::value>> -bool operator!=(const T& one, gsl::basic_string_span<CharT, Extent> other) noexcept +bool operator!=(const T& one, gsl::basic_string_span<CharT, Extent> other) { return !(one == other); } @@ -503,7 +501,7 @@ bool operator!=(const T& one, gsl::basic_string_span<CharT, Extent> other) noexc template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T, typename = std::enable_if_t<std::is_convertible< T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>> -bool operator<(gsl::basic_string_span<CharT, Extent> one, const T& other) noexcept +bool operator<(gsl::basic_string_span<CharT, Extent> one, const T& other) { const gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(other); return std::lexicographical_compare(one.begin(), one.end(), tmp.begin(), tmp.end()); @@ -514,7 +512,7 @@ template < typename = std::enable_if_t< std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value && !gsl::details::is_basic_string_span<T>::value>> -bool operator<(const T& one, gsl::basic_string_span<CharT, Extent> other) noexcept +bool operator<(const T& one, gsl::basic_string_span<CharT, Extent> other) { gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(one); return std::lexicographical_compare(tmp.begin(), tmp.end(), other.begin(), other.end()); @@ -533,7 +531,7 @@ template < std::is_convertible<DataType*, CharT*>::value && std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>> -bool operator<(gsl::basic_string_span<CharT, Extent> one, const T& other) noexcept +bool operator<(gsl::basic_string_span<CharT, Extent> one, const T& other) { gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(other); return std::lexicographical_compare(one.begin(), one.end(), tmp.begin(), tmp.end()); @@ -547,7 +545,7 @@ template < std::is_convertible<DataType*, CharT*>::value && std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>> -bool operator<(const T& one, gsl::basic_string_span<CharT, Extent> other) noexcept +bool operator<(const T& one, gsl::basic_string_span<CharT, Extent> other) { gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(one); return std::lexicographical_compare(tmp.begin(), tmp.end(), other.begin(), other.end()); @@ -558,7 +556,7 @@ bool operator<(const T& one, gsl::basic_string_span<CharT, Extent> other) noexce template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T, typename = std::enable_if_t<std::is_convertible< T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>> -bool operator<=(gsl::basic_string_span<CharT, Extent> one, const T& other) noexcept +bool operator<=(gsl::basic_string_span<CharT, Extent> one, const T& other) { return !(other < one); } @@ -568,7 +566,7 @@ template < typename = std::enable_if_t< std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value && !gsl::details::is_basic_string_span<T>::value>> -bool operator<=(const T& one, gsl::basic_string_span<CharT, Extent> other) noexcept +bool operator<=(const T& one, gsl::basic_string_span<CharT, Extent> other) { return !(other < one); } @@ -586,7 +584,7 @@ template < std::is_convertible<DataType*, CharT*>::value && std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>> -bool operator<=(gsl::basic_string_span<CharT, Extent> one, const T& other) noexcept +bool operator<=(gsl::basic_string_span<CharT, Extent> one, const T& other) { return !(other < one); } @@ -599,7 +597,7 @@ template < std::is_convertible<DataType*, CharT*>::value && std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>> -bool operator<=(const T& one, gsl::basic_string_span<CharT, Extent> other) noexcept +bool operator<=(const T& one, gsl::basic_string_span<CharT, Extent> other) { return !(other < one); } @@ -609,7 +607,7 @@ bool operator<=(const T& one, gsl::basic_string_span<CharT, Extent> other) noexc template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T, typename = std::enable_if_t<std::is_convertible< T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>> -bool operator>(gsl::basic_string_span<CharT, Extent> one, const T& other) noexcept +bool operator>(gsl::basic_string_span<CharT, Extent> one, const T& other) { return other < one; } @@ -619,7 +617,7 @@ template < typename = std::enable_if_t< std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value && !gsl::details::is_basic_string_span<T>::value>> -bool operator>(const T& one, gsl::basic_string_span<CharT, Extent> other) noexcept +bool operator>(const T& one, gsl::basic_string_span<CharT, Extent> other) { return other < one; } @@ -637,7 +635,7 @@ template < std::is_convertible<DataType*, CharT*>::value && std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>> -bool operator>(gsl::basic_string_span<CharT, Extent> one, const T& other) noexcept +bool operator>(gsl::basic_string_span<CharT, Extent> one, const T& other) { return other < one; } @@ -650,7 +648,7 @@ template < std::is_convertible<DataType*, CharT*>::value && std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>> -bool operator>(const T& one, gsl::basic_string_span<CharT, Extent> other) noexcept +bool operator>(const T& one, gsl::basic_string_span<CharT, Extent> other) { return other < one; } @@ -660,7 +658,7 @@ bool operator>(const T& one, gsl::basic_string_span<CharT, Extent> other) noexce template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T, typename = std::enable_if_t<std::is_convertible< T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>> -bool operator>=(gsl::basic_string_span<CharT, Extent> one, const T& other) noexcept +bool operator>=(gsl::basic_string_span<CharT, Extent> one, const T& other) { return !(one < other); } @@ -670,7 +668,7 @@ template < typename = std::enable_if_t< std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value && !gsl::details::is_basic_string_span<T>::value>> -bool operator>=(const T& one, gsl::basic_string_span<CharT, Extent> other) noexcept +bool operator>=(const T& one, gsl::basic_string_span<CharT, Extent> other) { return !(one < other); } @@ -688,7 +686,7 @@ template < std::is_convertible<DataType*, CharT*>::value && std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>> -bool operator>=(gsl::basic_string_span<CharT, Extent> one, const T& other) noexcept +bool operator>=(gsl::basic_string_span<CharT, Extent> one, const T& other) { return !(one < other); } @@ -701,7 +699,7 @@ template < std::is_convertible<DataType*, CharT*>::value && std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>> -bool operator>=(const T& one, gsl::basic_string_span<CharT, Extent> other) noexcept +bool operator>=(const T& one, gsl::basic_string_span<CharT, Extent> other) { return !(one < other); } |