From f165706505c214903f1743082d8ba1063c4fcfd3 Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Tue, 25 Feb 2025 23:25:14 +0100 Subject: Add ASL_FWD_LIKE --- asl/base/utility.hpp | 2 ++ asl/base/utility_tests.cpp | 79 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) (limited to 'asl') diff --git a/asl/base/utility.hpp b/asl/base/utility.hpp index b3fb36b..b8e13ae 100644 --- a/asl/base/utility.hpp +++ b/asl/base/utility.hpp @@ -7,6 +7,8 @@ #define ASL_FWD(expr_) (static_cast(expr_)) +#define ASL_FWD_LIKE(ref_, expr_) (static_cast<::asl::copy_cref_t>(expr_)) + namespace asl { diff --git a/asl/base/utility_tests.cpp b/asl/base/utility_tests.cpp index 4b8e3d1..d959369 100644 --- a/asl/base/utility_tests.cpp +++ b/asl/base/utility_tests.cpp @@ -1 +1,80 @@ #include "asl/base/utility.hpp" +#include "asl/testing/testing.hpp" + +template static constexpr int identify(const T&) { return 1; } +template static constexpr int identify(const T&&) { return 2; } +template static constexpr int identify(T&) { return 3; } +template static constexpr int identify(T&&) { return 4; } + +struct IdentifySelf +{ + template + constexpr int get(this Self&& self) { return identify(ASL_FWD(self)); } +}; + +static int get_const_lref(const IdentifySelf& i) { return ASL_FWD(i).get(); } +static int get_const_rref(const IdentifySelf&& i) { return ASL_FWD(i).get(); } +static int get_lref(IdentifySelf& i) { return ASL_FWD(i).get(); } +static int get_rref(IdentifySelf&& i) { return ASL_FWD(i).get(); } + +ASL_TEST(forward) +{ + IdentifySelf id; + ASL_TEST_EXPECT(get_const_lref(id) == 1); + ASL_TEST_EXPECT(get_lref(id) == 3); + ASL_TEST_EXPECT(get_const_rref(ASL_MOVE(id)) == 2); + ASL_TEST_EXPECT(get_rref(ASL_MOVE(id)) == 4); +} + +ASL_TEST(move) +{ + IdentifySelf id; + ASL_TEST_EXPECT(id.get() == 3); + ASL_TEST_EXPECT(ASL_MOVE(id).get() == 4); +} + +struct Level1 +{ + IdentifySelf id; +}; + +struct Level2 +{ + Level1 deeper; +}; + +struct Level3 +{ + Level2 deeper; +}; + +static int get_const_lref(const Level3& i) { return ASL_FWD(i).deeper.deeper.id.get(); } +static int get_const_rref(const Level3&& i) { return ASL_FWD(i).deeper.deeper.id.get(); } +static int get_lref(Level3& i) { return ASL_FWD(i).deeper.deeper.id.get(); } +static int get_rref(Level3&& i) { return ASL_FWD(i).deeper.deeper.id.get(); } + +ASL_TEST(forward2) +{ + Level3 id{}; + ASL_TEST_EXPECT(get_const_lref(id) == 1); + ASL_TEST_EXPECT(get_lref(id) == 3); + ASL_TEST_EXPECT(get_const_rref(ASL_MOVE(id)) == 2); + ASL_TEST_EXPECT(get_rref(ASL_MOVE(id)) == 4); +} + +template +static int test_fwd_like(T&& t) +{ + IdentifySelf id; + return ASL_FWD_LIKE(decltype(t), id).get(); +} + +ASL_TEST(forward_like) +{ + int x{}; + ASL_TEST_EXPECT(test_fwd_like(x) == 1); + ASL_TEST_EXPECT(test_fwd_like(x) == 3); + ASL_TEST_EXPECT(test_fwd_like(ASL_MOVE(x)) == 2); + ASL_TEST_EXPECT(test_fwd_like(ASL_MOVE(x)) == 4); +} + -- cgit