mirror of
https://github.com/microsoft/GSL.git
synced 2026-07-04 23:50:54 +02:00
clang-format improvements (#1251)
* clang-format improvements - Add a clang-format linter check to the PR pipeline - Apply clang-format to files where the linter initially failed - Remove `CommentPragmas` from `.clang-format` - Remove all `// clang-format off` and `// NO-FORMAT` as they are not needed - Remove a commented out `GSL_SUPPRESS` * clang-format 20 * pipeline fail * Update .github/workflows/clang-format.yml Co-authored-by: Carson Radtke <nosrac925@gmail.com> * output used clang-format version * installed version is 18 which replaces "GSL_SUPPRESS(bounds.1)" with "GSL_SUPPRESS(bounds .1)" * only include/gsl, not include to prevent formatting of include/CMakeLists.txt * apply clang-format[-20] In a VS2026 developer command prompt I ran `clang-format -i include\gsl\* --assume-filename x.cpp`. This was necessary because VS GUI does not format files without an extension :(. Please note that `--assume-filename` is necessary here, otherwise the files will not be formatted. Surprisingly the behaviour for the formatter differs from the behaviour of `lang-format(-20) --dry-run --Werror include/gsl/*` where clang-format recognizes that the files is C++. * change "#if 0" back to original version with comments only * formatting scripts for windows and linux for linux with linter (shfmt and shellcheck) * add WhitespaceSensitiveMacros: [GSL_SUPPRESS] * provide path for clang-format (Windows) Currently not clear to me: On my personal computer at home, when I start "Developer Command Prompt for VS18", I can run `clang-format` without providing the path. On my managed (domain) company computer, when I start "Developer Command Prompt for VS18", I can NOT run `clang-format` without providing the path. I need to call `"%VCINSTALLDIR%Tools\Llvm\bin\clang-format"`. I have no idea what the difference is. At least the version `"%VCINSTALLDIR%Tools\Llvm\bin\clang-format"` works on both computers, so I add the path. --------- Co-authored-by: Werner Henze <w.henze@avm.de> Co-authored-by: Carson Radtke <nosrac925@gmail.com> Co-authored-by: Werner Henze <werner.henze+gitcommits@posteo.de>
This commit is contained in:
+1
-1
@@ -31,4 +31,4 @@ AlignConsecutiveAssignments: false
|
||||
AlignTrailingComments: true
|
||||
|
||||
SpaceAfterCStyleCast: true
|
||||
CommentPragmas: '^ NO-FORMAT:'
|
||||
WhitespaceSensitiveMacros: [GSL_SUPPRESS]
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
name: Code Formatting
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
CLANG_VERSION: "20"
|
||||
|
||||
jobs:
|
||||
clang-format:
|
||||
name: Run clang-format
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Install the exact clang-format binary
|
||||
- name: Install clang-format
|
||||
run: |
|
||||
sudo apt install clang-format-${{ env.CLANG_VERSION }}
|
||||
|
||||
# Prints the version of clang-format being used
|
||||
- name: Log clang-format version
|
||||
run: clang-format-${{ env.CLANG_VERSION }} --version
|
||||
|
||||
# Runs clang-format over the repository codebase
|
||||
- name: Check format
|
||||
run: |
|
||||
{
|
||||
find include/gsl -type f
|
||||
find tests -type f \( -name '*.cpp' -o -name '*.h' \)
|
||||
} | xargs clang-format-${{ env.CLANG_VERSION }} --dry-run --Werror
|
||||
@@ -0,0 +1,32 @@
|
||||
name: Shell script linter
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
clang-format:
|
||||
name: Run shfmt and shellcheck
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Install the needed binaries
|
||||
- name: Install shfmt and shellcheck
|
||||
run: |
|
||||
sudo apt install shfmt shellcheck
|
||||
|
||||
- name: Check format
|
||||
run: |
|
||||
find scripts -type f -name '*.sh' -exec shfmt -l {} \;
|
||||
|
||||
- name: Run shellcheck
|
||||
run: |
|
||||
find scripts -type f -name '*.sh' -exec shellcheck {} \;
|
||||
@@ -48,9 +48,7 @@ void copy(span<SrcElementType, SrcExtent> src, span<DestElementType, DestExtent>
|
||||
"Source range is longer than target range");
|
||||
|
||||
Expects(dest.size() >= src.size());
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(stl.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
GSL_SUPPRESS(stl.1)
|
||||
std::copy_n(src.data(), src.size(), dest.data());
|
||||
}
|
||||
|
||||
|
||||
+1
-3
@@ -93,9 +93,7 @@ namespace details
|
||||
|
||||
typedef void(__cdecl* terminate_handler)();
|
||||
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(f.6) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
GSL_SUPPRESS(f.6)
|
||||
[[noreturn]] inline void __cdecl default_terminate_handler()
|
||||
{
|
||||
__fastfail(RANGE_CHECKS_FAILURE);
|
||||
|
||||
+18
-16
@@ -82,11 +82,13 @@ namespace gsl
|
||||
{
|
||||
#if GSL_USE_STD_BYTE
|
||||
|
||||
namespace impl {
|
||||
// impl::byte is used by gsl::as_bytes so our own code does not trigger a deprecation warning as would be the case when we used gsl::byte.
|
||||
// Users of GSL should only use gsl::byte, not gsl::impl::byte.
|
||||
using byte = std::byte;
|
||||
}
|
||||
namespace impl
|
||||
{
|
||||
// impl::byte is used by gsl::as_bytes so our own code does not trigger a deprecation warning as
|
||||
// would be the case when we used gsl::byte. Users of GSL should only use gsl::byte, not
|
||||
// gsl::impl::byte.
|
||||
using byte = std::byte;
|
||||
} // namespace impl
|
||||
|
||||
using byte GSL_DEPRECATED("Use std::byte instead.") = std::byte;
|
||||
|
||||
@@ -100,11 +102,13 @@ enum class byte_may_alias byte : unsigned char
|
||||
{
|
||||
};
|
||||
|
||||
namespace impl {
|
||||
// impl::byte is used by gsl::as_bytes so our own code does not trigger a deprecation warning as would be the case when we used gsl::byte.
|
||||
// Users of GSL should only use gsl::byte, not gsl::impl::byte.
|
||||
using byte = gsl::byte;
|
||||
}
|
||||
namespace impl
|
||||
{
|
||||
// impl::byte is used by gsl::as_bytes so our own code does not trigger a deprecation warning as
|
||||
// would be the case when we used gsl::byte. Users of GSL should only use gsl::byte, not
|
||||
// gsl::impl::byte.
|
||||
using byte = gsl::byte;
|
||||
} // namespace impl
|
||||
|
||||
template <class IntegerType, std::enable_if_t<std::is_integral<IntegerType>::value, bool> = true>
|
||||
constexpr byte& operator<<=(byte& b, IntegerType shift) noexcept
|
||||
@@ -170,15 +174,13 @@ constexpr IntegerType to_integer(byte b) noexcept
|
||||
|
||||
#endif // GSL_USE_STD_BYTE
|
||||
|
||||
|
||||
template <typename T>
|
||||
// NOTE: need suppression since c++14 does not allow "return {t}"
|
||||
// GSL_SUPPRESS(type.4) // NO-FORMAT: attribute // TODO: suppression does not work
|
||||
constexpr gsl::impl::byte to_byte(T t) noexcept
|
||||
{
|
||||
static_assert(std::is_same<T, unsigned char>::value,
|
||||
"gsl::to_byte(t) must be provided an unsigned char, otherwise data loss may occur. "
|
||||
"If you are calling to_byte with an integer constant use: gsl::to_byte<t>() version.");
|
||||
static_assert(
|
||||
std::is_same<T, unsigned char>::value,
|
||||
"gsl::to_byte(t) must be provided an unsigned char, otherwise data loss may occur. "
|
||||
"If you are calling to_byte with an integer constant use: gsl::to_byte<t>() version.");
|
||||
return gsl::impl::byte(t);
|
||||
}
|
||||
|
||||
|
||||
+7
-7
@@ -18,13 +18,13 @@
|
||||
#define GSL_GSL_H
|
||||
|
||||
// IWYU pragma: begin_exports
|
||||
#include "./algorithm" // copy
|
||||
#include "./assert" // Ensures/Expects
|
||||
#include "./byte" // byte
|
||||
#include "./pointers" // owner, not_null
|
||||
#include "./span" // span
|
||||
#include "./zstring" // zstring
|
||||
#include "./util" // finally()/narrow_cast()...
|
||||
#include "./algorithm" // copy
|
||||
#include "./assert" // Ensures/Expects
|
||||
#include "./byte" // byte
|
||||
#include "./pointers" // owner, not_null
|
||||
#include "./span" // span
|
||||
#include "./util" // finally()/narrow_cast()...
|
||||
#include "./zstring" // zstring
|
||||
|
||||
#ifdef __cpp_exceptions
|
||||
#include "./narrow" // narrow()
|
||||
|
||||
+20
-26
@@ -16,8 +16,8 @@
|
||||
|
||||
#ifndef GSL_NARROW_H
|
||||
#define GSL_NARROW_H
|
||||
#include "./assert" // for GSL_SUPPRESS
|
||||
#include "./util" // for narrow_cast
|
||||
#include "./assert" // for GSL_SUPPRESS
|
||||
#include "./util" // for narrow_cast
|
||||
#include <exception> // for std::exception
|
||||
namespace gsl
|
||||
{
|
||||
@@ -28,28 +28,28 @@ struct narrowing_error : public std::exception
|
||||
|
||||
// narrow() : a checked version of narrow_cast() that throws if the cast changed the value
|
||||
template <class T, class U, typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr>
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(es.46) // NO-FORMAT: attribute // The warning suggests that a floating->unsigned conversion can occur
|
||||
// in the static_cast below, and that gsl::narrow should be used instead.
|
||||
// Suppress this warning, since gsl::narrow is defined in terms of
|
||||
// static_cast
|
||||
// clang-format on
|
||||
GSL_SUPPRESS(type.1)
|
||||
GSL_SUPPRESS(es.46) // The warning suggests that a floating->unsigned conversion can occur
|
||||
// in the static_cast below, and that gsl::narrow should be used instead.
|
||||
// Suppress this warning, since gsl::narrow is defined in terms of
|
||||
// static_cast
|
||||
constexpr T narrow(U u)
|
||||
{
|
||||
constexpr const bool is_different_signedness =
|
||||
(std::is_signed<T>::value != std::is_signed<U>::value);
|
||||
|
||||
GSL_SUPPRESS(es.103) // NO-FORMAT: attribute // don't overflow
|
||||
GSL_SUPPRESS(es.104) // NO-FORMAT: attribute // don't underflow
|
||||
GSL_SUPPRESS(p.2) // NO-FORMAT: attribute // don't rely on undefined behavior
|
||||
const T t = narrow_cast<T>(u); // While this is technically undefined behavior in some cases (i.e., if the source value is of floating-point type
|
||||
// and cannot fit into the destination integral type), the resultant behavior is benign on the platforms
|
||||
// that we target (i.e., no hardware trap representations are hit).
|
||||
GSL_SUPPRESS(es.103) // don't overflow
|
||||
GSL_SUPPRESS(es.104) // don't underflow
|
||||
GSL_SUPPRESS(p.2) // don't rely on undefined behavior
|
||||
const T t = narrow_cast<T>(
|
||||
u); // While this is technically undefined behavior in some cases (i.e., if the source value
|
||||
// is of floating-point type and cannot fit into the destination integral type), the
|
||||
// resultant behavior is benign on the platforms that we target (i.e., no hardware trap
|
||||
// representations are hit).
|
||||
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||
#endif
|
||||
// Note: NaN will always throw, since NaN != NaN
|
||||
if (static_cast<U>(t) != u || (is_different_signedness && ((t < T{}) != (u < U{}))))
|
||||
@@ -57,24 +57,18 @@ GSL_SUPPRESS(p.2) // NO-FORMAT: attribute // don't rely on undefined behavior
|
||||
throw narrowing_error{};
|
||||
}
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
template <class T, class U, typename std::enable_if<!std::is_arithmetic<T>::value>::type* = nullptr>
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
constexpr T narrow(U u)
|
||||
GSL_SUPPRESS(type.1) constexpr T narrow(U u)
|
||||
{
|
||||
const T t = narrow_cast<T>(u);
|
||||
|
||||
if (static_cast<U>(t) != u)
|
||||
{
|
||||
throw narrowing_error{};
|
||||
}
|
||||
if (static_cast<U>(t) != u) { throw narrowing_error{}; }
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
+60
-41
@@ -18,13 +18,13 @@
|
||||
#define GSL_POINTERS_H
|
||||
|
||||
#include "./assert" // for Ensures, Expects
|
||||
#include "./util" // for GSL_DEPRECATED
|
||||
#include "./util" // for GSL_DEPRECATED
|
||||
|
||||
#include <cstddef> // for ptrdiff_t, nullptr_t, size_t
|
||||
#include <functional> // for less, greater
|
||||
#include <memory> // for shared_ptr, unique_ptr, hash
|
||||
#include <type_traits> // for enable_if_t, is_convertible, is_assignable
|
||||
#include <utility> // for declval, forward
|
||||
#include <cstddef> // for ptrdiff_t, nullptr_t, size_t
|
||||
#include <functional> // for less, greater
|
||||
#include <memory> // for shared_ptr, unique_ptr, hash
|
||||
#include <type_traits> // for enable_if_t, is_convertible, is_assignable
|
||||
#include <utility> // for declval, forward
|
||||
|
||||
#if !defined(GSL_NO_IOSTREAMS)
|
||||
#include <iosfwd> // for ostream
|
||||
@@ -48,15 +48,16 @@ namespace details
|
||||
{
|
||||
};
|
||||
|
||||
// Resolves to the more efficient of `const T` or `const T&`, in the context of returning a const-qualified value
|
||||
// of type T.
|
||||
// Resolves to the more efficient of `const T` or `const T&`, in the context of returning a
|
||||
// const-qualified value of type T.
|
||||
//
|
||||
// Copied from cppfront's implementation of the CppCoreGuidelines F.16 (https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#rf-in)
|
||||
template<typename T>
|
||||
using value_or_reference_return_t = std::conditional_t<
|
||||
sizeof(T) <= 2*sizeof(void*) && std::is_trivially_copy_constructible<T>::value,
|
||||
const T,
|
||||
const T&>;
|
||||
// Copied from cppfront's implementation of the CppCoreGuidelines F.16
|
||||
// (https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#rf-in)
|
||||
template <typename T>
|
||||
using value_or_reference_return_t =
|
||||
std::conditional_t<sizeof(T) <= 2 * sizeof(void*) &&
|
||||
std::is_trivially_copy_constructible<T>::value,
|
||||
const T, const T&>;
|
||||
|
||||
} // namespace details
|
||||
|
||||
@@ -72,9 +73,10 @@ using unique_ptr GSL_DEPRECATED("Use std::unique_ptr instead") = std::unique_ptr
|
||||
//
|
||||
// owner
|
||||
//
|
||||
// `gsl::owner<T>` is designed as a safety mechanism for code that must deal directly with raw pointers that own memory.
|
||||
// Ideally such code should be restricted to the implementation of low-level abstractions. `gsl::owner` can also be used
|
||||
// as a stepping point in converting legacy code to use more modern RAII constructs, such as smart pointers.
|
||||
// `gsl::owner<T>` is designed as a safety mechanism for code that must deal directly with raw
|
||||
// pointers that own memory. Ideally such code should be restricted to the implementation of
|
||||
// low-level abstractions. `gsl::owner` can also be used as a stepping point in converting legacy
|
||||
// code to use more modern RAII constructs, such as smart pointers.
|
||||
//
|
||||
// T must be a pointer type
|
||||
// - disallow construction from any type other than pointer type
|
||||
@@ -105,19 +107,23 @@ public:
|
||||
using element_type = T;
|
||||
|
||||
template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
|
||||
constexpr not_null(U&& u) noexcept(std::is_nothrow_move_constructible<T>::value) : ptr_(std::forward<U>(u))
|
||||
constexpr not_null(U&& u) noexcept(std::is_nothrow_move_constructible<T>::value)
|
||||
: ptr_(std::forward<U>(u))
|
||||
{
|
||||
Expects(ptr_ != nullptr);
|
||||
}
|
||||
|
||||
template <typename = std::enable_if_t<!std::is_same<std::nullptr_t, T>::value>>
|
||||
constexpr not_null(T u) noexcept(std::is_nothrow_move_constructible<T>::value) : ptr_(std::move(u))
|
||||
constexpr not_null(T u) noexcept(std::is_nothrow_move_constructible<T>::value)
|
||||
: ptr_(std::move(u))
|
||||
{
|
||||
Expects(ptr_ != nullptr);
|
||||
}
|
||||
|
||||
template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
|
||||
constexpr not_null(const not_null<U>& other) noexcept(std::is_nothrow_move_constructible<T>::value) : not_null(other.get())
|
||||
constexpr not_null(const not_null<U>& other) noexcept(
|
||||
std::is_nothrow_move_constructible<T>::value)
|
||||
: not_null(other.get())
|
||||
{}
|
||||
|
||||
not_null(const not_null& other) = default;
|
||||
@@ -151,7 +157,9 @@ private:
|
||||
T ptr_;
|
||||
};
|
||||
|
||||
template <typename T, std::enable_if_t<std::is_move_assignable<T>::value && std::is_move_constructible<T>::value, bool> = true>
|
||||
template <typename T, std::enable_if_t<std::is_move_assignable<T>::value &&
|
||||
std::is_move_constructible<T>::value,
|
||||
bool> = true>
|
||||
void swap(not_null<T>& a, not_null<T>& b) noexcept
|
||||
{
|
||||
a.swap(b);
|
||||
@@ -174,7 +182,7 @@ std::ostream& operator<<(std::ostream& os, const not_null<T>& val)
|
||||
|
||||
template <class T, class U>
|
||||
constexpr auto operator==(const not_null<T>& lhs,
|
||||
const not_null<U>& rhs) noexcept(noexcept(lhs.get() == rhs.get()))
|
||||
const not_null<U>& rhs) noexcept(noexcept(lhs.get() == rhs.get()))
|
||||
-> decltype(lhs.get() == rhs.get())
|
||||
{
|
||||
return lhs.get() == rhs.get();
|
||||
@@ -182,39 +190,41 @@ constexpr auto operator==(const not_null<T>& lhs,
|
||||
|
||||
template <class T, class U>
|
||||
constexpr auto operator!=(const not_null<T>& lhs,
|
||||
const not_null<U>& rhs) noexcept(noexcept(lhs.get() != rhs.get()))
|
||||
const not_null<U>& rhs) noexcept(noexcept(lhs.get() != rhs.get()))
|
||||
-> decltype(lhs.get() != rhs.get())
|
||||
{
|
||||
return lhs.get() != rhs.get();
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
constexpr auto operator<(const not_null<T>& lhs,
|
||||
const not_null<U>& rhs) noexcept(noexcept(std::less<>{}(lhs.get(), rhs.get())))
|
||||
-> decltype(std::less<>{}(lhs.get(), rhs.get()))
|
||||
constexpr auto operator<(const not_null<T>& lhs, const not_null<U>& rhs) noexcept(
|
||||
noexcept(std::less<>{}(lhs.get(), rhs.get()))) -> decltype(std::less<>{}(lhs.get(), rhs.get()))
|
||||
{
|
||||
return std::less<>{}(lhs.get(), rhs.get());
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
constexpr auto operator<=(const not_null<T>& lhs,
|
||||
const not_null<U>& rhs) noexcept(noexcept(std::less_equal<>{}(lhs.get(), rhs.get())))
|
||||
constexpr auto
|
||||
operator<=(const not_null<T>& lhs,
|
||||
const not_null<U>& rhs) noexcept(noexcept(std::less_equal<>{}(lhs.get(), rhs.get())))
|
||||
-> decltype(std::less_equal<>{}(lhs.get(), rhs.get()))
|
||||
{
|
||||
return std::less_equal<>{}(lhs.get(), rhs.get());
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
constexpr auto operator>(const not_null<T>& lhs,
|
||||
const not_null<U>& rhs) noexcept(noexcept(std::greater<>{}(lhs.get(), rhs.get())))
|
||||
constexpr auto
|
||||
operator>(const not_null<T>& lhs,
|
||||
const not_null<U>& rhs) noexcept(noexcept(std::greater<>{}(lhs.get(), rhs.get())))
|
||||
-> decltype(std::greater<>{}(lhs.get(), rhs.get()))
|
||||
{
|
||||
return std::greater<>{}(lhs.get(), rhs.get());
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
constexpr auto operator>=(const not_null<T>& lhs,
|
||||
const not_null<U>& rhs) noexcept(noexcept(std::greater_equal<>{}(lhs.get(), rhs.get())))
|
||||
constexpr auto
|
||||
operator>=(const not_null<T>& lhs,
|
||||
const not_null<U>& rhs) noexcept(noexcept(std::greater_equal<>{}(lhs.get(), rhs.get())))
|
||||
-> decltype(std::greater_equal<>{}(lhs.get(), rhs.get()))
|
||||
{
|
||||
return std::greater_equal<>{}(lhs.get(), rhs.get());
|
||||
@@ -230,9 +240,10 @@ not_null<T> operator+(const not_null<T>&, std::ptrdiff_t) = delete;
|
||||
template <class T>
|
||||
not_null<T> operator+(std::ptrdiff_t, const not_null<T>&) = delete;
|
||||
|
||||
|
||||
// T is conceptually a pointer so we don't have to worry about it being a reference and violating std::hash requirements
|
||||
template <class T, class U = typename T::element_type, bool = std::is_default_constructible<std::hash<U>>::value>
|
||||
// T is conceptually a pointer so we don't have to worry about it being a reference and violating
|
||||
// std::hash requirements
|
||||
template <class T, class U = typename T::element_type,
|
||||
bool = std::is_default_constructible<std::hash<U>>::value>
|
||||
struct not_null_hash
|
||||
{
|
||||
std::size_t operator()(const T& value) const noexcept { return std::hash<U>{}(value.get()); }
|
||||
@@ -282,24 +293,32 @@ class strict_not_null : public not_null<T>
|
||||
{
|
||||
public:
|
||||
template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
|
||||
constexpr explicit strict_not_null(U&& u) noexcept(std::is_nothrow_move_constructible<T>::value) : not_null<T>(std::forward<U>(u))
|
||||
constexpr explicit strict_not_null(U&& u) noexcept(std::is_nothrow_move_constructible<T>::value)
|
||||
: not_null<T>(std::forward<U>(u))
|
||||
{}
|
||||
|
||||
template <typename = std::enable_if_t<!std::is_same<std::nullptr_t, T>::value>>
|
||||
constexpr explicit strict_not_null(T u) noexcept(std::is_nothrow_move_constructible<T>::value) : not_null<T>(std::move(u))
|
||||
constexpr explicit strict_not_null(T u) noexcept(std::is_nothrow_move_constructible<T>::value)
|
||||
: not_null<T>(std::move(u))
|
||||
{}
|
||||
|
||||
template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
|
||||
constexpr strict_not_null(const not_null<U>& other) noexcept(std::is_nothrow_move_constructible<T>::value) : not_null<T>(other)
|
||||
constexpr strict_not_null(const not_null<U>& other) noexcept(
|
||||
std::is_nothrow_move_constructible<T>::value)
|
||||
: not_null<T>(other)
|
||||
{}
|
||||
|
||||
template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
|
||||
constexpr strict_not_null(const strict_not_null<U>& other) noexcept(std::is_nothrow_move_constructible<T>::value) : not_null<T>(other)
|
||||
constexpr strict_not_null(const strict_not_null<U>& other) noexcept(
|
||||
std::is_nothrow_move_constructible<T>::value)
|
||||
: not_null<T>(other)
|
||||
{}
|
||||
|
||||
// To avoid invalidating the "not null" invariant, the contained pointer is actually copied
|
||||
// instead of moved. If it is a custom pointer, its constructor could in theory throw exceptions.
|
||||
strict_not_null(strict_not_null&& other) noexcept(std::is_nothrow_copy_constructible<T>::value) = default;
|
||||
// instead of moved. If it is a custom pointer, its constructor could in theory throw
|
||||
// exceptions.
|
||||
strict_not_null(strict_not_null&& other) noexcept(
|
||||
std::is_nothrow_copy_constructible<T>::value) = default;
|
||||
strict_not_null(const strict_not_null& other) = default;
|
||||
strict_not_null& operator=(const strict_not_null& other) = default;
|
||||
strict_not_null& operator=(const not_null<T>& other)
|
||||
|
||||
+24
-45
@@ -163,9 +163,7 @@ namespace details
|
||||
constexpr span_iterator& operator++() noexcept
|
||||
{
|
||||
Expects(current_ != end_);
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
GSL_SUPPRESS(bounds.1)
|
||||
++current_;
|
||||
return *this;
|
||||
}
|
||||
@@ -196,9 +194,7 @@ namespace details
|
||||
if (n != 0) Expects(begin_ && current_ && end_);
|
||||
if (n > 0) Expects(end_ - current_ >= n);
|
||||
if (n < 0) Expects(current_ - begin_ >= -n);
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
GSL_SUPPRESS(bounds.1)
|
||||
current_ += n;
|
||||
return *this;
|
||||
}
|
||||
@@ -315,9 +311,7 @@ namespace details
|
||||
if (n < 0) Expects(current_ - begin_ >= -n);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
GSL_SUPPRESS(bounds.1)
|
||||
constexpr pointer _Unwrapped() const noexcept
|
||||
{ // after seeking *this to a high water mark, or using one of the
|
||||
// _Verify_xxx functions above, unwrap this span_iterator to a raw
|
||||
@@ -332,9 +326,7 @@ namespace details
|
||||
#else
|
||||
static constexpr bool _Unwrap_when_unverified = false;
|
||||
#endif
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(con.3) // NO-FORMAT: attribute // TODO: false positive
|
||||
// clang-format on
|
||||
GSL_SUPPRESS(con.3) // TODO: false positive
|
||||
constexpr void _Seek_to(const pointer p) noexcept
|
||||
{ // adjust the position of *this to previously verified location p
|
||||
// after _Unwrapped
|
||||
@@ -349,7 +341,8 @@ namespace details
|
||||
template <typename Ptr>
|
||||
friend struct std::pointer_traits;
|
||||
};
|
||||
}} // namespace gsl::details
|
||||
} // namespace details
|
||||
} // namespace gsl
|
||||
|
||||
namespace std
|
||||
{
|
||||
@@ -364,7 +357,10 @@ struct pointer_traits<::gsl::details::span_iterator<Type>>
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
namespace gsl { namespace details {
|
||||
namespace gsl
|
||||
{
|
||||
namespace details
|
||||
{
|
||||
template <std::size_t Ext>
|
||||
class extent_type
|
||||
{
|
||||
@@ -589,10 +585,7 @@ public:
|
||||
}
|
||||
|
||||
template <std::size_t Count>
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
constexpr span<element_type, Count> last() const noexcept
|
||||
GSL_SUPPRESS(bounds.1) constexpr span<element_type, Count> last() const noexcept
|
||||
{
|
||||
static_assert(Extent == dynamic_extent || Count <= Extent,
|
||||
"last() cannot extract more elements from a span than it contains.");
|
||||
@@ -601,10 +594,7 @@ public:
|
||||
}
|
||||
|
||||
template <std::size_t Offset, std::size_t Count = dynamic_extent>
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
constexpr auto subspan() const noexcept ->
|
||||
GSL_SUPPRESS(bounds.1) constexpr auto subspan() const noexcept ->
|
||||
typename details::calculate_subspan_type<ElementType, Extent, Offset, Count>::type
|
||||
{
|
||||
static_assert(Extent == dynamic_extent || (Extent >= Offset && (Count == dynamic_extent ||
|
||||
@@ -642,9 +632,7 @@ public:
|
||||
constexpr bool empty() const noexcept { return size() == 0; }
|
||||
|
||||
// [span.elem], span element access
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
GSL_SUPPRESS(bounds.1)
|
||||
constexpr reference operator[](size_type idx) const noexcept
|
||||
{
|
||||
Expects(idx < size());
|
||||
@@ -669,18 +657,14 @@ public:
|
||||
constexpr iterator begin() const noexcept
|
||||
{
|
||||
const auto data = storage_.data();
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
GSL_SUPPRESS(bounds.1)
|
||||
return {data, data + size(), data};
|
||||
}
|
||||
|
||||
constexpr iterator end() const noexcept
|
||||
{
|
||||
const auto data = storage_.data();
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
GSL_SUPPRESS(bounds.1)
|
||||
const auto endData = data + storage_.size();
|
||||
return {data, endData, endData};
|
||||
}
|
||||
@@ -693,9 +677,7 @@ public:
|
||||
constexpr pointer _Unchecked_begin() const noexcept { return data(); }
|
||||
constexpr pointer _Unchecked_end() const noexcept
|
||||
{
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
GSL_SUPPRESS(bounds.1)
|
||||
return data() + size();
|
||||
}
|
||||
#endif // _MSC_VER
|
||||
@@ -752,9 +734,7 @@ private:
|
||||
return tmp.subspan(offset, count);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
GSL_SUPPRESS(bounds.1)
|
||||
constexpr span<element_type, dynamic_extent>
|
||||
make_subspan(size_type offset, size_type count, subspan_selector<dynamic_extent>) const noexcept
|
||||
{
|
||||
@@ -792,7 +772,9 @@ span(const Container&) -> span<Element>;
|
||||
#if defined(GSL_USE_STATIC_CONSTEXPR_WORKAROUND)
|
||||
#if defined(__clang__) && defined(_MSC_VER) && defined(__cplusplus) && (__cplusplus < 201703L)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated" // Bug in clang-cl.exe which raises a C++17 -Wdeprecated warning about this static constexpr workaround in C++14 mode.
|
||||
#pragma clang diagnostic ignored \
|
||||
"-Wdeprecated" // Bug in clang-cl.exe which raises a C++17 -Wdeprecated warning about this
|
||||
// static constexpr workaround in C++14 mode.
|
||||
#endif // defined(__clang__) && defined(_MSC_VER) && defined(__cplusplus) && (__cplusplus < 201703L)
|
||||
template <class ElementType, std::size_t Extent>
|
||||
constexpr const typename span<ElementType, Extent>::size_type span<ElementType, Extent>::extent;
|
||||
@@ -827,11 +809,10 @@ template <class ElementType, std::size_t Extent>
|
||||
span<const gsl::impl::byte, details::calculate_byte_size<ElementType, Extent>::value>
|
||||
as_bytes(span<ElementType, Extent> s) noexcept
|
||||
{
|
||||
using type = span<const gsl::impl::byte, details::calculate_byte_size<ElementType, Extent>::value>;
|
||||
using type =
|
||||
span<const gsl::impl::byte, details::calculate_byte_size<ElementType, Extent>::value>;
|
||||
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
GSL_SUPPRESS(type.1)
|
||||
return type{reinterpret_cast<const gsl::impl::byte*>(s.data()), s.size_bytes()};
|
||||
}
|
||||
|
||||
@@ -842,9 +823,7 @@ as_writable_bytes(span<ElementType, Extent> s) noexcept
|
||||
{
|
||||
using type = span<gsl::impl::byte, details::calculate_byte_size<ElementType, Extent>::value>;
|
||||
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
GSL_SUPPRESS(type.1)
|
||||
return type{reinterpret_cast<gsl::impl::byte*>(s.data()), s.size_bytes()};
|
||||
}
|
||||
|
||||
|
||||
+23
-28
@@ -21,8 +21,8 @@
|
||||
|
||||
#include <array>
|
||||
#include <cstddef> // for ptrdiff_t, size_t
|
||||
#include <limits> // for numeric_limits
|
||||
#include <initializer_list> // for initializer_list
|
||||
#include <limits> // for numeric_limits
|
||||
#include <type_traits> // for is_signed, integral_constant
|
||||
#include <utility> // for exchange, forward
|
||||
|
||||
@@ -100,18 +100,21 @@ template <class F>
|
||||
class final_action
|
||||
{
|
||||
public:
|
||||
explicit final_action(const F& ff) noexcept : f{ff} { }
|
||||
explicit final_action(F&& ff) noexcept : f{std::move(ff)} { }
|
||||
explicit final_action(const F& ff) noexcept : f{ff} {}
|
||||
explicit final_action(F&& ff) noexcept : f{std::move(ff)} {}
|
||||
|
||||
~final_action() noexcept { if (invoke) f(); }
|
||||
~final_action() noexcept
|
||||
{
|
||||
if (invoke) f();
|
||||
}
|
||||
|
||||
final_action(final_action&& other) noexcept
|
||||
: f(std::move(other.f)), invoke(std::exchange(other.invoke, false))
|
||||
{ }
|
||||
{}
|
||||
|
||||
final_action(const final_action&) = delete;
|
||||
final_action(const final_action&) = delete;
|
||||
void operator=(const final_action&) = delete;
|
||||
void operator=(final_action&&) = delete;
|
||||
void operator=(final_action&&) = delete;
|
||||
|
||||
private:
|
||||
F f;
|
||||
@@ -127,10 +130,7 @@ GSL_NODISCARD auto finally(F&& f) noexcept
|
||||
|
||||
// narrow_cast(): a searchable way to do narrowing casts of values
|
||||
template <class T, class U>
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
constexpr T narrow_cast(U&& u) noexcept
|
||||
GSL_SUPPRESS(type.1) constexpr T narrow_cast(U&& u) noexcept
|
||||
{
|
||||
return static_cast<T>(std::forward<U>(u));
|
||||
}
|
||||
@@ -139,23 +139,17 @@ GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
// at() - Bounds-checked way of accessing builtin arrays, std::array, std::vector
|
||||
//
|
||||
template <class T, std::size_t N>
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
constexpr T& at(T (&arr)[N], const index i)
|
||||
GSL_SUPPRESS(bounds.4) GSL_SUPPRESS(bounds.2) constexpr T& at(T (&arr)[N], const index i)
|
||||
{
|
||||
static_assert(N <= static_cast<std::size_t>((std::numeric_limits<std::ptrdiff_t>::max)()), "We only support arrays up to PTRDIFF_MAX bytes.");
|
||||
static_assert(N <= static_cast<std::size_t>((std::numeric_limits<std::ptrdiff_t>::max)()),
|
||||
"We only support arrays up to PTRDIFF_MAX bytes.");
|
||||
Expects(i >= 0 && i < narrow_cast<index>(N));
|
||||
return arr[narrow_cast<std::size_t>(i)];
|
||||
}
|
||||
|
||||
template <class Cont>
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
constexpr auto at(Cont& cont, const index i) -> decltype(cont[cont.size()])
|
||||
GSL_SUPPRESS(bounds.4) GSL_SUPPRESS(bounds.2) constexpr auto at(Cont& cont, const index i)
|
||||
-> decltype(cont[cont.size()])
|
||||
{
|
||||
Expects(i >= 0 && i < narrow_cast<index>(cont.size()));
|
||||
using size_type = decltype(cont.size());
|
||||
@@ -163,17 +157,18 @@ GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
|
||||
}
|
||||
|
||||
template <class T>
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
constexpr T at(const std::initializer_list<T> cont, const index i)
|
||||
GSL_SUPPRESS(bounds.1) constexpr T at(const std::initializer_list<T> cont, const index i)
|
||||
{
|
||||
Expects(i >= 0 && i < narrow_cast<index>(cont.size()));
|
||||
return *(cont.begin() + i);
|
||||
}
|
||||
|
||||
template <class T, std::enable_if_t<std::is_move_assignable<T>::value && std::is_move_constructible<T>::value>>
|
||||
void swap(T& a, T& b) { std::swap(a, b); }
|
||||
template <class T, std::enable_if_t<std::is_move_assignable<T>::value &&
|
||||
std::is_move_constructible<T>::value>>
|
||||
void swap(T& a, T& b)
|
||||
{
|
||||
std::swap(a, b);
|
||||
}
|
||||
|
||||
#if defined(__cpp_lib_span) && __cpp_lib_span >= 202002L
|
||||
template <class T, std::size_t extent = std::dynamic_extent>
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@
|
||||
|
||||
#include "./span_ext" // for dynamic_extent
|
||||
|
||||
#include <cstddef> // for size_t, nullptr_t
|
||||
#include <cstddef> // for size_t, nullptr_t
|
||||
|
||||
namespace gsl
|
||||
{
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
@echo off
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
"%VCINSTALLDIR%Tools\Llvm\bin\clang-format" -version
|
||||
if %errorlevel% neq 0 (
|
||||
echo [ERROR] clang-format not found, script should be called from a visual studio developer command prompt.
|
||||
exit /b %errorlevel%
|
||||
)
|
||||
|
||||
for %%f in (include\gsl\* tests\*.h tests\*.cpp) do (
|
||||
echo formatting %%f
|
||||
"%VCINSTALLDIR%Tools\Llvm\bin\clang-format" -i --assume-filename x.cpp "%%f"
|
||||
)
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
cf=clang-format-$(grep -i 'CLANG_VERSION:' .github/workflows/clang-format.yml | sed -E 's/.*"([^"]+)".*/\1/')
|
||||
readonly cf
|
||||
|
||||
if ! "${cf}" -version; then
|
||||
echo "[ERROR] clang-format not found. Please install it using: sudo apt install ${cf}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
{
|
||||
find include/gsl -type f
|
||||
find tests -type f \( -name '*.cpp' -o -name '*.h' \)
|
||||
} | xargs "${cf}" -i --assume-filename=x.cpp --verbose
|
||||
|
||||
find scripts -type f -name '*.sh' -print -exec shfmt -w {} \;
|
||||
+2
-2
@@ -32,7 +32,7 @@
|
||||
TEST(at_tests, static_array)
|
||||
{
|
||||
int a[4] = {1, 2, 3, 4};
|
||||
const int(&c_a)[4] = a;
|
||||
const int (&c_a)[4] = a;
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
@@ -152,7 +152,7 @@ TEST(at_tests, std_span)
|
||||
static constexpr bool test_constexpr()
|
||||
{
|
||||
int a1[4] = {1, 2, 3, 4};
|
||||
const int(&c_a1)[4] = a1;
|
||||
const int (&c_a1)[4] = a1;
|
||||
std::array<int, 4> a2 = {1, 2, 3, 4};
|
||||
const std::array<int, 4>& c_a2 = a2;
|
||||
|
||||
|
||||
@@ -171,8 +171,8 @@ static_assert(!RShiftAssignCompilesFor<float>, "!RShiftAssignCompilesFor<float>"
|
||||
template <typename U, typename = void>
|
||||
static constexpr bool ToIntegerCompilesFor = false;
|
||||
template <typename U>
|
||||
static constexpr bool
|
||||
ToIntegerCompilesFor<U, void_t<decltype(gsl::to_integer<U>(gsl::byte{}))>> = true;
|
||||
static constexpr bool ToIntegerCompilesFor<U, void_t<decltype(gsl::to_integer<U>(gsl::byte{}))>> =
|
||||
true;
|
||||
static_assert(!ToIntegerCompilesFor<float>, "!ToIntegerCompilesFor<float>");
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -28,15 +28,15 @@ constexpr bool comparison_test(const int* ptr1, const int* ptr2)
|
||||
const not_null<const int*> p1(ptr1);
|
||||
const not_null<const int*> p1_same(ptr1);
|
||||
const not_null<const int*> p2(ptr2);
|
||||
|
||||
|
||||
// Testing operator==
|
||||
const bool eq_result = (p1 == p1_same); // Should be true
|
||||
const bool neq_result = (p1 != p2); // Should be true
|
||||
|
||||
|
||||
// Testing operator<= and operator>=
|
||||
const bool le_result = (p1 <= p1_same); // Should be true
|
||||
const bool ge_result = (p1 >= p1_same); // Should be true
|
||||
|
||||
|
||||
// The exact comparison results will depend on pointer ordering,
|
||||
// but we can verify that the basic equality checks work as expected
|
||||
return eq_result && neq_result && le_result && ge_result;
|
||||
@@ -47,11 +47,11 @@ constexpr bool workaround_test(const int* ptr1, const int* ptr2)
|
||||
const not_null<const int*> p1(ptr1);
|
||||
const not_null<const int*> p1_same(ptr1);
|
||||
const not_null<const int*> p2(ptr2);
|
||||
|
||||
|
||||
// Using .get() to compare
|
||||
const bool eq_result = (p1.get() == p1_same.get()); // Should be true
|
||||
const bool neq_result = (p1.get() != p2.get()); // Should be true
|
||||
|
||||
|
||||
return eq_result && neq_result;
|
||||
}
|
||||
} // namespace
|
||||
@@ -59,8 +59,10 @@ constexpr bool workaround_test(const int* ptr1, const int* ptr2)
|
||||
constexpr int test_value1 = 1;
|
||||
constexpr int test_value2 = 2;
|
||||
|
||||
static_assert(comparison_test(&test_value1, &test_value2), "not_null comparison operators should be constexpr");
|
||||
static_assert(workaround_test(&test_value1, &test_value2), "not_null .get() comparison workaround should work");
|
||||
static_assert(comparison_test(&test_value1, &test_value2),
|
||||
"not_null comparison operators should be constexpr");
|
||||
static_assert(workaround_test(&test_value1, &test_value2),
|
||||
"not_null .get() comparison workaround should work");
|
||||
|
||||
TEST(notnull_constexpr_tests, TestNotNullConstexprComparison)
|
||||
{
|
||||
@@ -71,4 +73,3 @@ TEST(notnull_constexpr_tests, TestNotNullConstexprComparison)
|
||||
EXPECT_TRUE(comparison_test(&value1, &value2));
|
||||
EXPECT_TRUE(workaround_test(&value1, &value2));
|
||||
}
|
||||
|
||||
|
||||
+8
-24
@@ -69,9 +69,7 @@ struct CustomPtr
|
||||
template <typename T, typename U>
|
||||
std::string operator==(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
{
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
GSL_SUPPRESS(type.1)
|
||||
return reinterpret_cast<const void*>(lhs.p_) == reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||
: "false";
|
||||
}
|
||||
@@ -79,9 +77,7 @@ std::string operator==(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
template <typename T, typename U>
|
||||
std::string operator!=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
{
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
GSL_SUPPRESS(type.1)
|
||||
return reinterpret_cast<const void*>(lhs.p_) != reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||
: "false";
|
||||
}
|
||||
@@ -89,9 +85,7 @@ std::string operator!=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
template <typename T, typename U>
|
||||
std::string operator<(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
{
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
GSL_SUPPRESS(type.1)
|
||||
return reinterpret_cast<const void*>(lhs.p_) < reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||
: "false";
|
||||
}
|
||||
@@ -99,9 +93,7 @@ std::string operator<(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
template <typename T, typename U>
|
||||
std::string operator>(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
{
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
GSL_SUPPRESS(type.1)
|
||||
return reinterpret_cast<const void*>(lhs.p_) > reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||
: "false";
|
||||
}
|
||||
@@ -109,9 +101,7 @@ std::string operator>(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
template <typename T, typename U>
|
||||
std::string operator<=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
{
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
GSL_SUPPRESS(type.1)
|
||||
return reinterpret_cast<const void*>(lhs.p_) <= reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||
: "false";
|
||||
}
|
||||
@@ -119,9 +109,7 @@ std::string operator<=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
template <typename T, typename U>
|
||||
std::string operator>=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||
{
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
GSL_SUPPRESS(type.1)
|
||||
return reinterpret_cast<const void*>(lhs.p_) >= reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||
: "false";
|
||||
}
|
||||
@@ -137,13 +125,9 @@ struct NonCopyableNonMovable
|
||||
|
||||
namespace
|
||||
{
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
GSL_SUPPRESS(f.4)
|
||||
bool helper(not_null<int*> p) { return *p == 12; }
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
GSL_SUPPRESS(f.4)
|
||||
bool helper_const(not_null<const int*> p) { return *p == 12; }
|
||||
|
||||
int* return_pointer() { return nullptr; }
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
using namespace gsl;
|
||||
|
||||
GSL_SUPPRESS(f.23) // NO-FORMAT: attribute
|
||||
GSL_SUPPRESS(f.23)
|
||||
void f(int* i) { *i += 1; }
|
||||
|
||||
TEST(owner_tests, basic_test)
|
||||
@@ -43,8 +43,7 @@ using void_t = void;
|
||||
template <typename U, typename = void>
|
||||
static constexpr bool OwnerCompilesFor = false;
|
||||
template <typename U>
|
||||
static constexpr bool OwnerCompilesFor<U, void_t<decltype(gsl::owner<U>{})>> =
|
||||
true;
|
||||
static constexpr bool OwnerCompilesFor<U, void_t<decltype(gsl::owner<U>{})>> = true;
|
||||
static_assert(OwnerCompilesFor<int*>, "OwnerCompilesFor<int*>");
|
||||
static_assert(!OwnerCompilesFor<int>, "!OwnerCompilesFor<int>");
|
||||
static_assert(!OwnerCompilesFor<std::shared_ptr<int>>, "!OwnerCompilesFor<std::shared_ptr<int>>");
|
||||
|
||||
@@ -44,7 +44,8 @@ TEST(pointers_test, swap)
|
||||
gsl::not_null<std::unique_ptr<int>> a(std::make_unique<int>(0));
|
||||
gsl::not_null<std::unique_ptr<int>> b(std::make_unique<int>(1));
|
||||
|
||||
static_assert(noexcept(gsl::swap(a, b)), "not null unique_ptr should be noexcept-swappable");
|
||||
static_assert(noexcept(gsl::swap(a, b)),
|
||||
"not null unique_ptr should be noexcept-swappable");
|
||||
|
||||
EXPECT_TRUE(*a == 0);
|
||||
EXPECT_TRUE(*b == 1);
|
||||
@@ -65,7 +66,8 @@ TEST(pointers_test, swap)
|
||||
gsl::strict_not_null<std::unique_ptr<int>> a{std::make_unique<int>(0)};
|
||||
gsl::strict_not_null<std::unique_ptr<int>> b{std::make_unique<int>(1)};
|
||||
|
||||
static_assert(noexcept(gsl::swap(a, b)), "strict not null unique_ptr should be noexcept-swappable");
|
||||
static_assert(noexcept(gsl::swap(a, b)),
|
||||
"strict not null unique_ptr should be noexcept-swappable");
|
||||
|
||||
EXPECT_TRUE(*a == 0);
|
||||
EXPECT_TRUE(*b == 1);
|
||||
|
||||
@@ -61,10 +61,10 @@ void ArrayConvertibilityCheck()
|
||||
|
||||
static_assert(std::is_same<decltype(gsl::span{stl_nullptr}), gsl::span<T*, 3>>::value,
|
||||
"std::is_same< decltype(span{stl_nullptr}), span<T*, 3>>::value");
|
||||
static_assert(
|
||||
std::is_same<decltype(gsl::span{std::as_const(stl_nullptr)}), gsl::span<T* const, 3>>::value,
|
||||
"std::is_same< decltype(span{std::as_const(stl_nullptr)}), span<T* const, "
|
||||
"3>>::value");
|
||||
static_assert(std::is_same<decltype(gsl::span{std::as_const(stl_nullptr)}),
|
||||
gsl::span<T* const, 3>>::value,
|
||||
"std::is_same< decltype(span{std::as_const(stl_nullptr)}), span<T* const, "
|
||||
"3>>::value");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ TEST(span_ext_test, make_span_from_array_constructor)
|
||||
|
||||
TEST(span_ext_test, make_span_from_dynamic_array_constructor)
|
||||
{
|
||||
double(*arr)[3][4] = new double[100][3][4];
|
||||
double (*arr)[3][4] = new double[100][3][4];
|
||||
|
||||
{
|
||||
auto s = make_span(&arr[0][0][0], 10);
|
||||
|
||||
@@ -257,7 +257,9 @@ TEST(span_test, from_pointer_pointer_construction)
|
||||
EXPECT_TRUE(s.data() == &arr[0]);
|
||||
}
|
||||
|
||||
//{ // this test succeeds on all platforms, gsl::span is more relaxed than std::span where this would be UB
|
||||
// this test succeeds on all platforms, gsl::span is more relaxed than std::span where this
|
||||
// would be UB
|
||||
//{
|
||||
// auto workaround_macro = [&]() { span<int> s{&arr[1], &arr[0]}; };
|
||||
// EXPECT_DEATH(workaround_macro(), expected);
|
||||
//}
|
||||
@@ -342,7 +344,7 @@ TEST(span_test, from_array_constructor)
|
||||
|
||||
TEST(span_test, from_dynamic_array_constructor)
|
||||
{
|
||||
double(*arr)[3][4] = new double[100][3][4];
|
||||
double (*arr)[3][4] = new double[100][3][4];
|
||||
|
||||
{
|
||||
span<double> s(&arr[0][0][0], 10);
|
||||
|
||||
@@ -41,24 +41,16 @@ struct RefCounted
|
||||
|
||||
namespace
|
||||
{
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
GSL_SUPPRESS(f.4)
|
||||
bool helper(not_null<int*> p) { return *p == 12; }
|
||||
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
GSL_SUPPRESS(f.4)
|
||||
bool helper_const(not_null<const int*> p) { return *p == 12; }
|
||||
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
GSL_SUPPRESS(f.4)
|
||||
bool strict_helper(strict_not_null<int*> p) { return *p == 12; }
|
||||
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
GSL_SUPPRESS(f.4)
|
||||
bool strict_helper_const(strict_not_null<const int*> p) { return *p == 12; }
|
||||
|
||||
int* return_pointer() { return nullptr; }
|
||||
@@ -195,7 +187,6 @@ template <typename U>
|
||||
static constexpr bool
|
||||
StrictHelperCompilesFor<U, void_t<decltype(strict_helper(std::declval<U>()))>> = true;
|
||||
|
||||
|
||||
template <typename U, typename = void>
|
||||
static constexpr bool StrictHelperConstCompilesFor = false;
|
||||
template <typename U>
|
||||
@@ -203,7 +194,6 @@ static constexpr bool
|
||||
StrictHelperConstCompilesFor<U, void_t<decltype(strict_helper_const(std::declval<U>()))>> =
|
||||
true;
|
||||
|
||||
|
||||
template <typename U, typename = void>
|
||||
static constexpr bool HelperCompilesFor = false;
|
||||
template <typename U>
|
||||
@@ -219,13 +209,12 @@ TEST(strict_notnull_tests, TestStrictNotNull)
|
||||
strict_not_null<int*> snn = &x;
|
||||
#endif
|
||||
static_assert(!StrictHelperCompilesFor<int*>, "!StrictHelperCompilesFor<int*>");
|
||||
static_assert(!StrictHelperConstCompilesFor<int*>,
|
||||
"!StrictHelperCompilesFor<int*>");
|
||||
static_assert(!StrictHelperConstCompilesFor<int*>, "!StrictHelperCompilesFor<int*>");
|
||||
|
||||
const strict_not_null<int*> snn1{&x};
|
||||
|
||||
static_assert(StrictHelperCompilesFor<const strict_not_null<int*>>,
|
||||
"StrictHelperCompilesFor<const strict_not_null<int*>>");
|
||||
"StrictHelperCompilesFor<const strict_not_null<int*>>");
|
||||
helper(snn1);
|
||||
helper_const(snn1);
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <algorithm> // for move
|
||||
#include <algorithm> // for move
|
||||
#include <complex>
|
||||
#include <cstddef> // for std::ptrdiff_t
|
||||
#include <cstdint> // for uint32_t, int32_t
|
||||
@@ -156,8 +156,8 @@ TEST(utils_tests, narrow)
|
||||
n = -42;
|
||||
EXPECT_THROW(narrow<unsigned>(n), narrowing_error);
|
||||
|
||||
EXPECT_TRUE(
|
||||
narrow<std::complex<float>>(std::complex<double>(4, 2)) == std::complex<float>(4, 2));
|
||||
EXPECT_TRUE(narrow<std::complex<float>>(std::complex<double>(4, 2)) ==
|
||||
std::complex<float>(4, 2));
|
||||
EXPECT_THROW(narrow<std::complex<float>>(std::complex<double>(4.2)), narrowing_error);
|
||||
|
||||
EXPECT_TRUE(narrow<int>(float(1)) == 1);
|
||||
|
||||
Reference in New Issue
Block a user