diff --git a/include/zll/memory/address_of.hpp b/include/zll/memory/address_of.hpp new file mode 100644 index 0000000..395ae9b --- /dev/null +++ b/include/zll/memory/address_of.hpp @@ -0,0 +1,28 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#ifndef ZLL_MEMORY_ADDRESSOF_HPP +#define ZLL_MEMORY_ADDRESSOF_HPP + +#include "zll/meta/enable_if.hpp" +#include "zll/meta/is_object.hpp" +#include "zll/utils/attribute_macros.hpp" + +namespace zll { + +template +ZLL_FORCE_INLINE typename meta::enable_if::value, T*>::type addressof(T& arg) { + return reinterpret_cast(&const_cast(reinterpret_cast(arg))); +} + +template +ZLL_FORCE_INLINE typename meta::enable_if::value, T*>::type addressof(T& arg) { + return &arg; +} + +} // namespace zll + +#endif // ZLL_MEMORY_ADDRESSOF_HPP diff --git a/include/zll/utils/attribute_macros.hpp b/include/zll/utils/attribute_macros.hpp new file mode 100644 index 0000000..329e1df --- /dev/null +++ b/include/zll/utils/attribute_macros.hpp @@ -0,0 +1,13 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#ifndef ZLL_UTILS_ATTRIBUTEMACROS_HPP +#define ZLL_UTILS_ATTRIBUTEMACROS_HPP + +#define ZLL_FORCE_INLINE inline __attribute__ ((__always_inline__)) +#define ZLl_NEVER_INLINE __attribute__ ((__noinline__)) + +#endif // ZLL_UTILS_ATTRIBUTEMACROS_HPP diff --git a/tests/unit_tests/memory/address_of_tests.cpp b/tests/unit_tests/memory/address_of_tests.cpp new file mode 100644 index 0000000..d350a7f --- /dev/null +++ b/tests/unit_tests/memory/address_of_tests.cpp @@ -0,0 +1,44 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include "zll/memory/address_of.hpp" + +#include + +// clang-format off +void test_fn0() {} +void test_fn1(int) {} +void test_fn2(int, int) {} +void test_fn3(int, int, int) {} +// clang-format on + +UTEST(memory_address_of, scalar) { + float* ptr = new float(); + float& ref = *ptr; + + ASSERT_TRUE(zll::addressof(ref) == ptr); + delete ptr; +} + +UTEST(memory_address_of, function) { + ASSERT_TRUE(zll::addressof(test_fn0) == &test_fn0); + ASSERT_TRUE(zll::addressof(test_fn1) == &test_fn1); + ASSERT_TRUE(zll::addressof(test_fn2) == &test_fn2); + ASSERT_TRUE(zll::addressof(test_fn3) == &test_fn3); +} + +UTEST(memory_address_of, array) { + { + int arr[3] = {17, 12, 32}; + int(*ptr)[3] = &arr; + ASSERT_TRUE(zll::addressof(arr) == ptr); + } + { + const char arr[3] = {17, 12, 32}; + const char(*ptr)[3] = &arr; + ASSERT_TRUE(zll::addressof(arr) == ptr); + } +} diff --git a/tests/unit_tests/meson.build b/tests/unit_tests/meson.build index 55235b2..522145f 100644 --- a/tests/unit_tests/meson.build +++ b/tests/unit_tests/meson.build @@ -1,5 +1,7 @@ unit_tests_srcs = [ + 'memory/address_of_tests.cpp', + 'meta/enable_if_tests.cpp', 'meta/integral_constant_tests.cpp', 'meta/is_arithmetic_tests.cpp',