diff options
author | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2025-02-25 23:25:14 +0100 |
---|---|---|
committer | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2025-02-25 23:27:26 +0100 |
commit | f165706505c214903f1743082d8ba1063c4fcfd3 (patch) | |
tree | 8807968b9f1f2185d7241a50879d2ca33f34566a /asl | |
parent | 507a994399c9ddf7e78bd4a290e05f54ddc2f3a6 (diff) |
Add ASL_FWD_LIKE
Diffstat (limited to 'asl')
-rw-r--r-- | asl/base/utility.hpp | 2 | ||||
-rw-r--r-- | asl/base/utility_tests.cpp | 79 |
2 files changed, 81 insertions, 0 deletions
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<decltype(expr_)&&>(expr_)) +#define ASL_FWD_LIKE(ref_, expr_) (static_cast<::asl::copy_cref_t<ref_, decltype(expr_)&&>>(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<typename T> static constexpr int identify(const T&) { return 1; } +template<typename T> static constexpr int identify(const T&&) { return 2; } +template<typename T> static constexpr int identify(T&) { return 3; } +template<typename T> static constexpr int identify(T&&) { return 4; } + +struct IdentifySelf +{ + template<typename Self> + 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<typename T> +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<const int&>(x) == 1); + ASL_TEST_EXPECT(test_fwd_like<int&>(x) == 3); + ASL_TEST_EXPECT(test_fwd_like<const int&&>(ASL_MOVE(x)) == 2); + ASL_TEST_EXPECT(test_fwd_like<int&&>(ASL_MOVE(x)) == 4); +} + |