mirror of
https://github.com/ETLCPP/etl.git
synced 2026-04-30 19:09:10 +08:00
Add const specialization for etl::get_object_at (#1217)
Signed-off-by: Filipe Cuim <filipemocuim@gmail.com>
This commit is contained in:
parent
b6e78b7c9c
commit
43d3f0e89c
@ -60,8 +60,8 @@ namespace etl
|
||||
//*****************************************************************************
|
||||
template <typename T>
|
||||
ETL_CONSTEXPR T* to_address(T* p) ETL_NOEXCEPT
|
||||
{
|
||||
return p;
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
@ -837,7 +837,7 @@ namespace etl
|
||||
|
||||
std::uninitialized_value_construct(o_begin, o_end);
|
||||
}
|
||||
#else
|
||||
#else
|
||||
//*****************************************************************************
|
||||
/// Default initialises a range of objects to uninitialised memory.
|
||||
/// https://en.cppreference.com/w/cpp/memory/uninitialized_value_construct
|
||||
@ -1264,7 +1264,7 @@ namespace etl
|
||||
|
||||
//*********************************
|
||||
template <typename U>
|
||||
default_delete(const default_delete<U>&) ETL_NOEXCEPT
|
||||
default_delete(const default_delete<U>&) ETL_NOEXCEPT
|
||||
{
|
||||
}
|
||||
|
||||
@ -1353,8 +1353,8 @@ namespace etl
|
||||
#endif
|
||||
|
||||
//*********************************
|
||||
unique_ptr(pointer p_, typename etl::conditional<etl::is_reference<TDeleter>::value,
|
||||
TDeleter,
|
||||
unique_ptr(pointer p_, typename etl::conditional<etl::is_reference<TDeleter>::value,
|
||||
TDeleter,
|
||||
typename etl::add_lvalue_reference<const TDeleter>::type>::type deleter_) ETL_NOEXCEPT
|
||||
: p(p_)
|
||||
, deleter(deleter_)
|
||||
@ -1557,7 +1557,7 @@ namespace etl
|
||||
#endif
|
||||
|
||||
//*********************************
|
||||
unique_ptr(pointer p_,
|
||||
unique_ptr(pointer p_,
|
||||
typename etl::conditional<etl::is_reference<TDeleter>::value,
|
||||
TDeleter,
|
||||
typename etl::add_lvalue_reference<const TDeleter>::type>::type deleter_) ETL_NOEXCEPT
|
||||
@ -1614,7 +1614,7 @@ namespace etl
|
||||
{
|
||||
pointer value = p;
|
||||
p = ETL_NULLPTR;
|
||||
return value;
|
||||
return value;
|
||||
}
|
||||
|
||||
//*********************************
|
||||
@ -1709,7 +1709,7 @@ namespace etl
|
||||
unique_ptr(const unique_ptr&) ETL_DELETE;
|
||||
unique_ptr& operator =(const unique_ptr&) ETL_DELETE;
|
||||
|
||||
pointer p;
|
||||
pointer p;
|
||||
TDeleter deleter;
|
||||
};
|
||||
}
|
||||
@ -2324,7 +2324,7 @@ namespace etl
|
||||
reinterpret_cast<const void*>(sb),
|
||||
sizeof(T) * n);
|
||||
#endif
|
||||
|
||||
|
||||
return db;
|
||||
}
|
||||
|
||||
@ -2374,7 +2374,7 @@ namespace etl
|
||||
reinterpret_cast<const void*>(sb),
|
||||
sizeof(T) * n);
|
||||
#endif
|
||||
|
||||
|
||||
return db;
|
||||
}
|
||||
|
||||
@ -2438,7 +2438,7 @@ namespace etl
|
||||
/// \return The destination
|
||||
//***************************************************************************
|
||||
template <typename TPointer, typename T>
|
||||
typename etl::enable_if<etl::is_pointer<TPointer>::value &&
|
||||
typename etl::enable_if<etl::is_pointer<TPointer>::value &&
|
||||
!etl::is_const<TPointer>::value &&
|
||||
etl::is_integral<T>::value &&
|
||||
sizeof(T) == 1, TPointer>::type
|
||||
@ -2447,11 +2447,11 @@ namespace etl
|
||||
ETL_STATIC_ASSERT(etl::is_trivially_copyable<typename etl::iterator_traits<TPointer>::value_type>::value, "Cannot mem_set a non trivially copyable type");
|
||||
|
||||
#if ETL_USING_BUILTIN_MEMSET
|
||||
__builtin_memset(reinterpret_cast<void*>(db),
|
||||
__builtin_memset(reinterpret_cast<void*>(db),
|
||||
static_cast<char>(value),
|
||||
sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(de - db));
|
||||
#else
|
||||
::memset(reinterpret_cast<void*>(db),
|
||||
::memset(reinterpret_cast<void*>(db),
|
||||
static_cast<char>(value),
|
||||
sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(de - db));
|
||||
#endif
|
||||
@ -2504,13 +2504,13 @@ namespace etl
|
||||
mem_char(TPointer sb, TPointer se, T value) ETL_NOEXCEPT
|
||||
{
|
||||
#if ETL_USING_BUILTIN_MEMCHR
|
||||
void* result = __builtin_memchr(reinterpret_cast<void*>(sb),
|
||||
void* result = __builtin_memchr(reinterpret_cast<void*>(sb),
|
||||
static_cast<char>(value),
|
||||
sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(se - sb));
|
||||
|
||||
return (result == 0U) ? reinterpret_cast<char*>(se) : reinterpret_cast<char*>(result);
|
||||
#else
|
||||
void* result = ::memchr(reinterpret_cast<void*>(sb),
|
||||
void* result = ::memchr(reinterpret_cast<void*>(sb),
|
||||
static_cast<char>(value),
|
||||
sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(se - sb));
|
||||
|
||||
@ -2527,7 +2527,7 @@ namespace etl
|
||||
//***************************************************************************
|
||||
template <typename TPointer, typename T>
|
||||
ETL_NODISCARD
|
||||
typename etl::enable_if<etl::is_pointer<TPointer>::value &&
|
||||
typename etl::enable_if<etl::is_pointer<TPointer>::value &&
|
||||
etl::is_const<typename etl::remove_pointer<TPointer>::type>::value &&
|
||||
etl::is_integral<T>::value &&
|
||||
sizeof(T) == 1, const char*>::type
|
||||
@ -2545,7 +2545,7 @@ namespace etl
|
||||
sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(se - sb));
|
||||
|
||||
return (result == 0U) ? reinterpret_cast<const char*>(se) : reinterpret_cast<const char*>(result);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
@ -2557,25 +2557,25 @@ namespace etl
|
||||
//***************************************************************************
|
||||
template <typename TPointer, typename T>
|
||||
ETL_NODISCARD
|
||||
typename etl::enable_if<etl::is_pointer<TPointer>::value &&
|
||||
typename etl::enable_if<etl::is_pointer<TPointer>::value &&
|
||||
!etl::is_const<typename etl::remove_pointer<TPointer>::type>::value &&
|
||||
etl::is_integral<T>::value &&
|
||||
sizeof(T) == 1, char*>::type
|
||||
mem_char(TPointer sb, size_t n, T value) ETL_NOEXCEPT
|
||||
{
|
||||
#if ETL_USING_BUILTIN_MEMCHR
|
||||
void* result = __builtin_memchr(reinterpret_cast<void*>(sb),
|
||||
void* result = __builtin_memchr(reinterpret_cast<void*>(sb),
|
||||
static_cast<char>(value),
|
||||
sizeof(typename etl::iterator_traits<TPointer>::value_type) * n);
|
||||
|
||||
return (result == 0U) ? reinterpret_cast<char*>(sb + n) : reinterpret_cast<char*>(result);
|
||||
#else
|
||||
void* result = ::memchr(reinterpret_cast<void*>(sb),
|
||||
void* result = ::memchr(reinterpret_cast<void*>(sb),
|
||||
static_cast<char>(value),
|
||||
sizeof(typename etl::iterator_traits<TPointer>::value_type) * n);
|
||||
|
||||
return (result == 0U) ? reinterpret_cast<char*>(sb + n) : reinterpret_cast<char*>(result);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
@ -2587,7 +2587,7 @@ namespace etl
|
||||
//***************************************************************************
|
||||
template <typename TPointer, typename T>
|
||||
ETL_NODISCARD
|
||||
typename etl::enable_if<etl::is_pointer<TPointer>::value &&
|
||||
typename etl::enable_if<etl::is_pointer<TPointer>::value &&
|
||||
etl::is_const<typename etl::remove_pointer<TPointer>::type>::value &&
|
||||
etl::is_integral<T>::value &&
|
||||
sizeof(T) == 1, const char*>::type
|
||||
@ -2607,7 +2607,7 @@ namespace etl
|
||||
return (result == 0U) ? reinterpret_cast<const char*>(sb + n) : reinterpret_cast<const char*>(result);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
@ -2687,9 +2687,20 @@ namespace etl
|
||||
ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
|
||||
#endif
|
||||
|
||||
TObject& v = *reinterpret_cast<TObject*>(p);
|
||||
return *reinterpret_cast<TObject*>(p);
|
||||
}
|
||||
|
||||
return v;
|
||||
//*****************************************************************************
|
||||
/// Get the container at const 'p'.
|
||||
//*****************************************************************************
|
||||
template <typename TObject>
|
||||
const TObject& get_object_at(const void* p)
|
||||
{
|
||||
#if ETL_IS_DEBUG_BUILD
|
||||
ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
|
||||
#endif
|
||||
|
||||
return *reinterpret_cast<const TObject*>(p);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
|
||||
@ -1256,7 +1256,7 @@ namespace
|
||||
uint32_t expected[8] = { 0x12345678, 0x76543210, 0x01452367, 0x23670145, 0x67234501, 0x45016723, 0x01324576, 0x76453201 };
|
||||
uint32_t data[12] = { 0x12345678, 0x76543210, 0x01452367, 0x23670145, 0x67234501, 0x45016723, 0x01324576, 0x76453201, 0, 0, 0, 0 };
|
||||
const uint32_t* data_begin = &data[0];
|
||||
|
||||
|
||||
uint32_t* result = etl::mem_move(data_begin, 8, data + 4);
|
||||
CHECK(std::equal(expected, expected + 8, data + 4));
|
||||
CHECK(result == data + 4);
|
||||
@ -1269,7 +1269,7 @@ namespace
|
||||
uint32_t same[8] = { 0x12345678, 0x76543210, 0x01452367, 0x23670145, 0x67234501, 0x45016723, 0x01324576, 0x76453201 };
|
||||
uint32_t grtr[8] = { 0x12345678, 0x76543210, 0x01452367, 0x23670145, 0x67235501, 0x45016723, 0x01324576, 0x76453201 };
|
||||
uint32_t less[8] = { 0x12345678, 0x76543210, 0x01452367, 0x23670145, 0x67134501, 0x45016723, 0x01324576, 0x76453201 };
|
||||
|
||||
|
||||
CHECK(etl::mem_compare(data, data + 8, same) == 0);
|
||||
CHECK(etl::mem_compare(data, data + 8, grtr) > 0);
|
||||
CHECK(etl::mem_compare(data, data + 8, less) < 0);
|
||||
@ -1443,7 +1443,7 @@ namespace
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
class Base
|
||||
class Base
|
||||
{
|
||||
public:
|
||||
virtual ~Base() {};
|
||||
@ -1452,21 +1452,21 @@ namespace
|
||||
|
||||
static bool function_was_called = false;
|
||||
|
||||
class Derived : public Base
|
||||
class Derived : public Base
|
||||
{
|
||||
public:
|
||||
Derived()
|
||||
Derived()
|
||||
{
|
||||
function_was_called = false;
|
||||
}
|
||||
|
||||
void function()
|
||||
void function()
|
||||
{
|
||||
function_was_called = true;
|
||||
}
|
||||
};
|
||||
|
||||
void call(etl::unique_ptr<Base> ptr)
|
||||
void call(etl::unique_ptr<Base> ptr)
|
||||
{
|
||||
ptr->function();
|
||||
}
|
||||
@ -1477,13 +1477,13 @@ namespace
|
||||
|
||||
etl::unique_ptr<Derived> ptr(new Derived());
|
||||
CHECK(ptr.get() != ETL_NULLPTR);
|
||||
|
||||
|
||||
call(etl::move(ptr));
|
||||
CHECK(function_was_called);
|
||||
CHECK(ptr.get() == ETL_NULLPTR);
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct Flags
|
||||
{
|
||||
Flags()
|
||||
@ -1530,7 +1530,7 @@ namespace
|
||||
int a;
|
||||
int b;
|
||||
};
|
||||
|
||||
|
||||
alignas(Data) char buffer1[sizeof(Data)];
|
||||
char* pbuffer1 = buffer1;
|
||||
|
||||
@ -1581,14 +1581,14 @@ namespace
|
||||
CHECK_FALSE(flags.destructed);
|
||||
CHECK_EQUAL(1, rdata1b.a);
|
||||
CHECK_EQUAL(2, rdata1b.b);
|
||||
|
||||
|
||||
flags.Clear();
|
||||
Data& rdata2b = etl::get_object_at<Data>(pbuffer2b);
|
||||
CHECK_FALSE(flags.constructed);
|
||||
CHECK_FALSE(flags.destructed);
|
||||
CHECK_EQUAL(data2.a, rdata2b.a);
|
||||
CHECK_EQUAL(data2.b, rdata2b.b);
|
||||
|
||||
|
||||
flags.Clear();
|
||||
Data& rdata3b = etl::get_object_at<Data>(pbuffer3b);
|
||||
CHECK_FALSE(flags.constructed);
|
||||
@ -1612,6 +1612,33 @@ namespace
|
||||
CHECK_TRUE(flags.destructed);
|
||||
}
|
||||
|
||||
TEST(test_get_object_at_const_specialization)
|
||||
{
|
||||
struct Data
|
||||
{
|
||||
Data()
|
||||
: a(1)
|
||||
, b(2)
|
||||
{
|
||||
flags.constructed = true;
|
||||
}
|
||||
|
||||
~Data() = default;
|
||||
|
||||
int a;
|
||||
int b;
|
||||
};
|
||||
|
||||
std::array<uint8_t, 32U> buffer{};
|
||||
etl::construct_object_at(buffer.data(), Data());
|
||||
const void* bufferPointer = buffer.data();
|
||||
|
||||
const Data& rdata = etl::get_object_at<Data>(bufferPointer);
|
||||
CHECK_TRUE(flags.constructed);
|
||||
CHECK_TRUE(rdata.a == 1);
|
||||
CHECK_TRUE(rdata.b == 2);
|
||||
}
|
||||
|
||||
TEST(test_construct_get_destroy_object_misaligned)
|
||||
{
|
||||
struct Data
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user