Skip to content

Commit

Permalink
Added etl::to_address
Browse files Browse the repository at this point in the history
  • Loading branch information
jwellbelove committed Jan 28, 2025
1 parent 1da482d commit ad9bda9
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 11 deletions.
63 changes: 53 additions & 10 deletions include/etl/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,49 @@ SOFTWARE.

namespace etl
{
#if ETL_USING_STL && ETL_USING_CPP20
//*****************************************************************************
/// Obtain the address represented by p without forming a reference to the object pointed to by p.
/// Defined when using the STL and C++20
//*****************************************************************************
template <typename TPtr>
constexpr auto to_address(const TPtr& p) noexcept
{
return std::to_address(p);
}

//*****************************************************************************
/// Obtain the address represented by p without forming a reference to the object pointed to by p.
/// Defined when using the STL and C++20
//*****************************************************************************
template <typename T>
constexpr T* to_address(T* p) noexcept
{
return std::to_address(p);
}
#else
//*****************************************************************************
/// Obtain the address represented by p without forming a reference to the object pointed to by p.
/// Defined when not using the STL or C++20
//*****************************************************************************
template <typename T>
ETL_CONSTEXPR T* to_address(T* p)
{
return p;
}

//*****************************************************************************
/// Obtain the address represented by itr without forming a reference to the object pointed to by itr.
/// Requires that the iterator defines operator->()
/// Defined when not using the STL or C++20
//*****************************************************************************
template <typename Iterator>
ETL_CONSTEXPR typename Iterator::pointer to_address(const Iterator& itr)
{
return itr.operator->();
}
#endif

#if ETL_USING_STL
//*****************************************************************************
/// Fills uninitialised memory range with a value.
Expand Down Expand Up @@ -112,7 +155,7 @@ namespace etl

while (o_begin != o_end)
{
::new (static_cast<void*>(etl::addressof(*o_begin))) value_type(value);
::new (static_cast<void*>(etl::to_address(o_begin))) value_type(value);
++o_begin;
}

Expand Down Expand Up @@ -259,7 +302,7 @@ namespace etl

while (i_begin != i_end)
{
::new (static_cast<void*>(etl::addressof(*o_end))) value_type(*i_begin);
::new (static_cast<void*>(etl::to_address(o_end))) value_type(*i_begin);
++i_begin;
++o_end;
}
Expand Down Expand Up @@ -407,7 +450,7 @@ namespace etl

while (i_begin != i_end)
{
::new (static_cast<void*>(etl::addressof(*o_end))) value_type(etl::move(*i_begin));
::new (static_cast<void*>(etl::to_address(o_end))) value_type(etl::move(*i_begin));
++i_begin;
++o_end;
}
Expand Down Expand Up @@ -532,7 +575,7 @@ namespace etl

while (n-- != 0)
{
::new (static_cast<void*>(etl::addressof(*o_end))) value_type(etl::move(*i_begin));
::new (static_cast<void*>(etl::to_address(o_end))) value_type(etl::move(*i_begin));
++i_begin;
++o_end;
}
Expand Down Expand Up @@ -665,7 +708,7 @@ namespace etl

while (o_begin != o_end)
{
::new (static_cast<void*>(etl::addressof(*o_begin))) value_type;
::new (static_cast<void*>(etl::to_address(o_begin))) value_type;
++o_begin;
}
}
Expand Down Expand Up @@ -844,7 +887,7 @@ namespace etl

while (o_begin != o_end)
{
::new (static_cast<void*>(etl::addressof(*o_begin))) value_type();
::new (static_cast<void*>(etl::to_address(o_begin))) value_type();
++o_begin;
}
}
Expand Down Expand Up @@ -1095,7 +1138,7 @@ namespace etl
{
while (i_begin != i_end)
{
etl::destroy_at(etl::addressof(*i_begin));
etl::destroy_at(etl::to_address(i_begin));
++i_begin;
}
}
Expand Down Expand Up @@ -1127,7 +1170,7 @@ namespace etl

while (i_begin != i_end)
{
etl::destroy_at(etl::addressof(*i_begin));
etl::destroy_at(etl::to_address(i_begin));
++i_begin;
}
}
Expand Down Expand Up @@ -1182,7 +1225,7 @@ namespace etl
{
while (n > 0)
{
etl::destroy_at(etl::addressof(*i_begin));
etl::destroy_at(etl::to_address(i_begin));
++i_begin;
--n;
}
Expand Down Expand Up @@ -1218,7 +1261,7 @@ namespace etl

while (n > 0)
{
etl::destroy_at(etl::addressof(*i_begin));
etl::destroy_at(etl::to_address(i_begin));
++i_begin;
--n;
}
Expand Down
18 changes: 17 additions & 1 deletion test/test_memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ SOFTWARE.
#include "unit_test_framework.h"

#include "etl/memory.h"
#include "etl/list.h"
#include "etl/debug_count.h"

#include "data.h"
Expand Down Expand Up @@ -1450,7 +1451,7 @@ namespace
CHECK(ptr.get() == ETL_NULLPTR);
}

//*************************************************************************

struct Flags
{
Flags()
Expand Down Expand Up @@ -1623,5 +1624,20 @@ namespace

CHECK_THROW(etl::destroy_object_at<Data>(pbuffer1), etl::alignment_error);
}

//*************************************************************************
TEST(test_to_address)
{
int i;
int* pi = &i;

etl::list<int, 4> container = { 1, 2, 3, 4 };
etl::list<int, 4>::iterator itr = container.begin();
std::advance(itr, 2);
int* plist_item = &*itr;

CHECK_EQUAL(&i, etl::to_address(pi));
CHECK_EQUAL(plist_item, etl::to_address(itr));
}
};
}

0 comments on commit ad9bda9

Please sign in to comment.