* improve performance of span_iterator w/ clang
Issue: #1165
Before this PR, the range-for loop was ~3300x slower. After this PR, it
is ~1.005x slower
The clang optimizer is very good at optimizing `current != end`, so
we changed to this idiom. This moves the Expects assertion into the
constructor instead of on the hot-path which is called whenever either
operator++ or operator* is called.
Note: The codegen for the assertion is still a missed optimization,
but less worrisome as it only happens once per iterator.
Note: benchmarks on M1 Macbook Pro w/ Apple Clang 16.0.0
* Remove unused headers from gsl/pointers
forward is already declared in utility, no need to include algorithm which is relativaly heavy
hash is already declared in memory, no need to bring brand-new header system_error for hash only
* Fix: add missing header <functional> to gsl/pointers due to using less/greater
Two warnings were being emitted in the MSVC+LLVM tests.
The warning `-Wunsafe-buffer-usage` is initially introduced in some capacity here https://reviews.llvm.org/D137346 pointing to documentation at https://discourse.llvm.org/t/rfc-c-buffer-hardening/65734. The warning is a stylistic checker whose goal is to "emit a warning every time an unsafe operation is performed on a raw pointer". This type of programming model is not useful for library implementations of types such as `span`, where direct manipulation of raw pointers is inevitable, so disable the warning altogether.
There is also a false-positive warning https://github.com/llvm/llvm-project/issues/65689 that I've disabled inline.
Without this change a `gsl::not_null<class_type>` triggers these `noexcept` warnings:
```
.../gsl/include/gsl/pointers:162:50: warning: noexcept-expression evaluates to ‘false’ because of a call to ‘constexpr gsl::details::value_or_reference_return_t<T> gsl::not_null<T>::get() const [with T = class_type*; gsl::details::value_or_reference_return_t<T> = class_type* const]’ [-Wnoexcept]
162 | const not_null<U>& rhs) noexcept(noexcept(lhs.get() == rhs.get()))
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.../gsl/include/gsl/pointers:119:55: note: but ‘constexpr gsl::details::value_or_reference_return_t<T> gsl::not_null<T>::get() const [with T = class_type*; gsl::details::value_or_reference_return_t<T> = class_type* const]’ does not throw; perhaps it should be declared ‘noexcept’
119 | constexpr details::value_or_reference_return_t<T> get() const
| ^~~
```
Co-authored-by: Werner Henze <w.henze@avm.de>
Headers that were previously prefixed with `gsl_` were renamed to drop the `gsl_` prefix in https://github.com/microsoft/GSL/pull/946, and the original version deprecated.
The deprecation happened a long time ago, so it is now time to remove these headers entirely.
Using `<`,`<=`,`>`,`>=` to compare unrelated pointers gives an unspecified result according to the standard.
This PR replaces the usage of these operators in `gsl::not_null` with the STL counterparts, which would leverage any implementation-defined strict total ordering for pointers.
Resolves#880
`size_bytes()` returns the span's size in bytes.
Assuming the span was constructed with an accurate size parameter, the check `size() < dynamic_extent / sizeof(element_type)` isn't required, since `size_t(-1)` (which is `dynamic_extent`) represents the size of the address space, so the number of bytes will never exceed it and in practice won't even come close.
Otherwise, it is not actually feasible to detect cases when the size parameter does not correspond to the dimensions of the underlying data pointer. In these cases, the relationship `size() < dynamic_extent / sizeof(element_type)` is simply one of many ways in which the `size()` could be incorrect, and serves no necessary purpose.
Resolves#1012
https://github.com/microsoft/GSL/issues/1075
- Add `static_assert` because we only support C style array `at` for up to half of the address space.
- Add `std::` before `size_t`.
- tests:
- Add `#include <exception>`
- Implement `span_tests` `interop_with_gsl_at` like `at_tests` `std_span`
This solves issue #1070 and removes the class `string_span`. The only content remaining in the header file `gsl/string_span` is the `*zstring` types.
This also removes the `string_span_tests.cpp` unit tests as these were only for the deprecated `string_span` class.
Co-authored-by: Werner Henze <werner.henze+gitcommits@posteo.de>
Guidelines issue 2006 removes the null check inside not_null::get, since the contained pointer is already guaranteed to be not-null upon construction.
Resolves#1051
- Move all install logic inside gsl_install.cmake
- This makes reading the logic easier, and avoids the enable language
issue with `GNUInstallDirs` by having it included after the project
call
- Have all functions inside gsl_functions.cmake
- Use CMake idiom PROJECT_IS_TOP_LEVEL
- Update README.md
Closes issue #550, which highlighted overhead in not_null::get for larger types such as shared_ptr. Every call to get would return a copy of the contained value.
This PR implements Herb's suggestion for changing the return type of not_null::get. The not_null's value will now only be copied if it is "trivially copyable"; otherwise, it will be returned by const reference.
Note: this change also forces the returned copy to be const.
Somewhere along the way, GSL's implementation of final_act and finally seems to have become way overthought. This PR is to re-simplify these facilities back to what C++ Core Guidelines C.30 said which is simple and clear and works. It just copies the invocable thing, and doesn't bother trying to optimize the copy. This should be fine, because we're typically passing something that's cheap to copy, often a stateless lambda.
The problem in #846 appears to be because finally looks like was originally written as a const&/&& overload (its state at the time that issue was opened)... to eliminate a copy when you invoke it with a temporary. If so, then the && was probably never intended to be a forwarder, but an rvalue reference that tripped over the horrid C++ syntax collision where a && parameter magically instead means a forwarding reference because the type happens to be a template parameter type here. So I suspect the original author was just trying to write an rvalue overload, and the forwarder that's there now was never intended at all.
GCC 4.8.0 - 7.0 has a bug (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480) involving specialization in a namespace enclosing the specialized template. This PR fixes an appearance of this bug in the span header.
Both checks for Expects(ExtentType::size() != dynamic_extent); in storage_type are always useless. storage_type<ExtentType> is only ever created with ExtentType == extent_type<Extent>, where Extent has type std::size_t and is the extent of the span.
Looking at extent_type<std::size_t Ext>::size():
- if Ext != dynamic_extent, then size() always returns Ext, and therefore size() != dynamic_extent
- if Ext == dynamic_extent, then size() returns extent_type<dynamic_extent>::size_. size_ can only be set via one of two constructors:
- constexpr explicit extent_type(size_type size), which already does the check in question
- constexpr explicit extent_type(extent_type<Other> ext) : size_(ext.size()), which simply relies on the other extent's size() method
So there is no way for ExtentType::size() == dynamic_extent.
This file uses std::exception, so it should include the appropriate header.
Normally it gets the STL's <exception> header included via the gsl/assert file, but this is skipped with _HAS_EXCEPTIONS=0. I understand _HAS_EXCEPTIONS is undocumented and unsupported, but regardless, the appropriate header should be included here.
Alternatively, gsl/narrow should be modified to support _HAS_EXCEPTIONS=0, like gsl/assert was. But I'm not proposing that change. <exception> does define std::exception even with _HAS_EXCEPTIONS=0.
In the implementation of gsl::narrow, there is a comparison `static_cast<U>(t) != u` which may be comparing two floats.
The comparison here is done purposefully to categorize ill effects of narrowing conversion, since the values being compared *should* be the same when compared with `operator==`.
Note, using #pragma GCC will suppress this warning for both GCC and Clang.
[SF.12: Prefer the quoted form of #include for files relative to the including file and the angle bracket form everywhere else](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rs-incform)
Additionally changed #include order in `span` so that all `span_ext` is in the GSL include block and not in the STL include block.
Fixes issues #1025.
Co-authored-by: Werner Henze <w.henze@avm.de>
* move span specialization of 'at' to <gsl/span> and update the parameter to be taken by reference
* undid previous changes and acted upon decisions made in maintainer sync. Fixed tests failing in /kernel mode
* ran clang-format on the include folder
* ran clang-format on the test folder
Co-authored-by: Jordan Maples <jordan.maples@microsoft.com>