mirror of
https://github.com/microsoft/GSL.git
synced 2025-08-01 03:34:28 +02:00
Add constexpr to not_null comparison operators (#1208)
* Initial plan for issue * Add test and plan to make not_null comparison functions constexpr Co-authored-by: carsonRadtke <10507970+carsonRadtke@users.noreply.github.com> * Add constexpr to not_null comparison operators Co-authored-by: carsonRadtke <10507970+carsonRadtke@users.noreply.github.com> * Fix copyright year in constexpr_notnull_tests.cpp Co-authored-by: carsonRadtke <10507970+carsonRadtke@users.noreply.github.com> * Fix constexpr tests for better compiler compatibility Co-authored-by: carsonRadtke <10507970+carsonRadtke@users.noreply.github.com> * Remove build artifacts and update .gitignore Co-authored-by: carsonRadtke <10507970+carsonRadtke@users.noreply.github.com> * Fix constexpr tests to be compatible with more compilers Co-authored-by: carsonRadtke <10507970+carsonRadtke@users.noreply.github.com> * copilot: Provide more project context for the Copilot coding agent (#1207) * copilot: create .github/copilot-instructions.md This file provides additional context and instructions to GitHub Copilot so it can better understand the codebase and coding conventions. More can be found about this file at the following links: - [Best practices for using Copilot to work on tasks](https://docs.github.com/en/enterprise-cloud@latest/copilot/using-github-copilot/using-copilot-coding-agent-to-work-on-tasks/best-practices-for-using-copilot-to-work-on-taskshttps://docs.github.com/en/enterprise-cloud@latest/copilot/using-github-copilot/using-copilot-coding-agent-to-work-on-tasks/best-practices-for-using-copilot-to-work-on-tasks) - [Adding repository custom instructions for GitHub Copilot](https://docs.github.com/en/enterprise-cloud@latest/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot?tool=webuihttps://docs.github.com/en/enterprise-cloud@latest/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot) * copilot: add copilot-setup-steps.yml This new workflow is done when copilot loads into an environment and enables copilot to be sure it has the proper dependencies before working on changes. Also included in the change are explicit instructions on what to do before reporting back "done". * Initial plan for issue * Rebase onto main and verify changes meet project guidelines Co-authored-by: carsonRadtke <10507970+carsonRadtke@users.noreply.github.com> * Update .gitignore to exclude build-cxx* directories Co-authored-by: carsonRadtke <10507970+carsonRadtke@users.noreply.github.com> * Fix newline at end of constexpr_notnull_tests.cpp and update .gitignore Co-authored-by: carsonRadtke <10507970+carsonRadtke@users.noreply.github.com> * Remove C++14 feature check that is redundant since C++14 is the minimum supported standard Co-authored-by: carsonRadtke <10507970+carsonRadtke@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: carsonRadtke <10507970+carsonRadtke@users.noreply.github.com> Co-authored-by: Carson Radtke <carsonradtke@microsoft.com>
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,5 +1,5 @@
|
||||
CMakeFiles
|
||||
build
|
||||
build*/
|
||||
tests/CMakeFiles
|
||||
tests/Debug
|
||||
*.opensdf
|
||||
|
@@ -173,7 +173,7 @@ std::ostream& operator<<(std::ostream& os, const not_null<T>& val)
|
||||
#endif // !defined(GSL_NO_IOSTREAMS)
|
||||
|
||||
template <class T, class U>
|
||||
auto operator==(const not_null<T>& lhs,
|
||||
constexpr auto operator==(const not_null<T>& lhs,
|
||||
const not_null<U>& rhs) noexcept(noexcept(lhs.get() == rhs.get()))
|
||||
-> decltype(lhs.get() == rhs.get())
|
||||
{
|
||||
@@ -181,7 +181,7 @@ auto operator==(const not_null<T>& lhs,
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
auto operator!=(const not_null<T>& lhs,
|
||||
constexpr auto operator!=(const not_null<T>& lhs,
|
||||
const not_null<U>& rhs) noexcept(noexcept(lhs.get() != rhs.get()))
|
||||
-> decltype(lhs.get() != rhs.get())
|
||||
{
|
||||
@@ -189,7 +189,7 @@ auto operator!=(const not_null<T>& lhs,
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
auto operator<(const not_null<T>& lhs,
|
||||
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()))
|
||||
{
|
||||
@@ -197,7 +197,7 @@ auto operator<(const not_null<T>& lhs,
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
auto operator<=(const not_null<T>& lhs,
|
||||
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()))
|
||||
{
|
||||
@@ -205,7 +205,7 @@ auto operator<=(const not_null<T>& lhs,
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
auto operator>(const not_null<T>& lhs,
|
||||
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()))
|
||||
{
|
||||
@@ -213,7 +213,7 @@ auto operator>(const not_null<T>& lhs,
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
auto operator>=(const not_null<T>& lhs,
|
||||
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()))
|
||||
{
|
||||
|
@@ -204,6 +204,7 @@ add_executable(gsl_tests
|
||||
assertion_tests.cpp
|
||||
at_tests.cpp
|
||||
byte_tests.cpp
|
||||
constexpr_notnull_tests.cpp
|
||||
notnull_tests.cpp
|
||||
owner_tests.cpp
|
||||
pointers_tests.cpp
|
||||
|
74
tests/constexpr_notnull_tests.cpp
Normal file
74
tests/constexpr_notnull_tests.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2025 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.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <gsl/pointers> // for not_null
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <type_traits> // for declval
|
||||
|
||||
using namespace gsl;
|
||||
|
||||
namespace
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
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");
|
||||
|
||||
TEST(notnull_constexpr_tests, TestNotNullConstexprComparison)
|
||||
{
|
||||
// This test simply verifies that the constexpr functions compile and run
|
||||
// If we got here, it means the constexpr comparison operators are working
|
||||
static const int value1 = 1;
|
||||
static const int value2 = 2;
|
||||
EXPECT_TRUE(comparison_test(&value1, &value2));
|
||||
EXPECT_TRUE(workaround_test(&value1, &value2));
|
||||
}
|
||||
|
Reference in New Issue
Block a user