Added constexpr. Removed some member functions. Removed 'move' member functions for etl::not_null<etl::unique_ptr<T, TDeleter>>

This commit is contained in:
John Wellbelove 2025-08-17 10:37:27 +01:00
parent 3bc87f1045
commit 3a25d5934a
9 changed files with 253 additions and 207 deletions

View File

@ -47,7 +47,7 @@ namespace etl
{
public:
not_null_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
not_null_exception(string_type reason_, string_type file_name_, numeric_type line_number_) ETL_NOEXCEPT_IF_NO_THROW
: exception(reason_, file_name_, line_number_)
{
}
@ -60,7 +60,7 @@ namespace etl
{
public:
not_null_contains_null(string_type file_name_, numeric_type line_number_)
not_null_contains_null(string_type file_name_, numeric_type line_number_) ETL_NOEXCEPT_IF_NO_THROW
: not_null_exception(ETL_ERROR_TEXT("not_null:contains null", ETL_NOT_NULL_FILE_ID"A"), file_name_, line_number_)
{
}
@ -93,47 +93,47 @@ namespace etl
/// Constructs a not_null from a pointer.
/// Asserts if the pointer is null.
//*********************************
explicit not_null(underlying_type ptr_)
ETL_CONSTEXPR14 explicit not_null(underlying_type ptr_) ETL_NOEXCEPT_IF_NO_THROW
: ptr(ptr_)
{
ETL_ASSERT(ptr_ != ETL_NULLPTR, ETL_ERROR(not_null_contains_null));
}
//*********************************
/// Copy constructor from a not_null pointer.
/// Copy construct from a not_null pointer.
//*********************************
not_null(const etl::not_null<T*>& other)
ETL_CONSTEXPR14 not_null(const etl::not_null<T*>& other) ETL_NOEXCEPT
: ptr(other.get())
{
}
//*********************************
/// Assignment from a pointer.
/// Asserts if the pointer is null.
//*********************************
ETL_CONSTEXPR14 not_null& operator =(underlying_type rhs) ETL_NOEXCEPT_IF_NO_THROW
{
ETL_ASSERT_OR_RETURN_VALUE(rhs != ETL_NULLPTR, ETL_ERROR(not_null_contains_null), *this);
ptr = rhs;
return *this;
}
//*********************************
/// Assignment from a not_null.
//*********************************
not_null& operator =(const etl::not_null<T*>& rhs)
ETL_CONSTEXPR14 not_null& operator =(const etl::not_null<T*>& rhs) ETL_NOEXCEPT
{
ptr = rhs.get();
return *this;
}
//*********************************
/// Assignment from a pointer.
/// Asserts if the pointer is null.
//*********************************
not_null& operator =(underlying_type rhs)
{
ETL_ASSERT_OR_RETURN_VALUE(rhs != ETL_NULLPTR, ETL_ERROR(not_null_contains_null), *this);
ptr = rhs;
return *this;
}
//*********************************
/// Gets the underlying pointer.
//*********************************
pointer get() const
ETL_CONSTEXPR14 pointer get() const ETL_NOEXCEPT
{
return ptr;
}
@ -141,7 +141,7 @@ namespace etl
//*********************************
/// Implicit conversion to pointer.
//*********************************
operator pointer() const
ETL_CONSTEXPR14 operator pointer() const ETL_NOEXCEPT
{
return ptr;
}
@ -149,31 +149,15 @@ namespace etl
//*********************************
/// Dereference operator.
//*********************************
reference operator*() const
ETL_CONSTEXPR14 reference operator*() const ETL_NOEXCEPT
{
return *ptr;
}
//*********************************
/// Arrow operator.
//*********************************
pointer operator->() const
{
return ptr;
}
//*********************************
/// Gets a reference to the underlying pointer.
//*********************************
underlying_type& underlying()
{
return ptr;
}
//*********************************
/// Gets a const_reference to the underlying pointer.
//*********************************
const underlying_type& underlying() const
ETL_CONSTEXPR14 pointer operator->() const ETL_NOEXCEPT
{
return ptr;
}
@ -191,6 +175,11 @@ namespace etl
template <typename T, typename TDeleter>
class not_null<etl::unique_ptr<T, TDeleter> >
{
private:
typedef etl::not_null<etl::unique_ptr<T, TDeleter> > this_type;
typedef etl::unique_ptr<T, TDeleter> underlying_type;
public:
typedef T value_type;
@ -199,32 +188,24 @@ namespace etl
typedef T& reference;
typedef const T& const_reference;
typedef etl::unique_ptr<T, TDeleter> underlying_type;;
#if ETL_USING_CPP11
//*********************************
/// Constructs a not_null from a unique_ptr.
/// Asserts if the unique_ptr is null.
/// Asserts if the unique_ptr contains null.
/// Moves from the unique_ptr.
//*********************************
explicit not_null(underlying_type&& u_ptr_)
ETL_CONSTEXPR14 explicit not_null(underlying_type&& u_ptr_) ETL_NOEXCEPT_IF_NO_THROW
: u_ptr(etl::move(u_ptr_))
{
ETL_ASSERT(u_ptr.get() != ETL_NULLPTR, ETL_ERROR(not_null_contains_null));
}
//*********************************
/// Constructs a not_null from a unique_ptr.
//*********************************
not_null(etl::not_null<underlying_type>&& other)
: u_ptr(etl::move(other.u_ptr))
{
}
//*********************************
/// Assign from a unique_ptr.
/// Asserts if the unique_ptr is null.
/// Asserts if the unique_ptr contains null.
/// Moves from the unique_ptr.
//*********************************
not_null& operator =(underlying_type&& rhs)
ETL_CONSTEXPR14 not_null& operator =(underlying_type&& rhs) ETL_NOEXCEPT_IF_NO_THROW
{
ETL_ASSERT_OR_RETURN_VALUE(rhs.get() != ETL_NULLPTR, ETL_ERROR(not_null_contains_null), *this);
@ -232,22 +213,12 @@ namespace etl
return *this;
}
//*********************************
/// Assign from a not_null.
//*********************************
not_null& operator =(etl::not_null<underlying_type>&& rhs)
{
u_ptr = etl::move(rhs.u_ptr);
return *this;
}
#endif
//*********************************
/// Gets the underlying ptr.
//*********************************
pointer get() const
ETL_CONSTEXPR14 pointer get() const ETL_NOEXCEPT
{
return u_ptr.get();
}
@ -255,7 +226,7 @@ namespace etl
//*********************************
/// Implicit conversion to pointer.
//*********************************
operator pointer() const
ETL_CONSTEXPR14 operator pointer() const ETL_NOEXCEPT
{
return u_ptr.get();
}
@ -263,7 +234,7 @@ namespace etl
//*********************************
/// Dereference operator.
//*********************************
reference operator*() const
ETL_CONSTEXPR14 reference operator*() const ETL_NOEXCEPT
{
return *u_ptr;
}
@ -271,29 +242,21 @@ namespace etl
//*********************************
/// Arrow operator.
//*********************************
pointer operator->() const
ETL_CONSTEXPR14 pointer operator->() const ETL_NOEXCEPT
{
return u_ptr.get();
}
//*********************************
/// Gets a reference to the underlying unique_ptr.
//*********************************
underlying_type& underlying()
{
return etl::move(u_ptr);
}
//*********************************
/// Gets a const_reference to the underlying unique_ptr.
//*********************************
const underlying_type& underlying() const
{
return etl::move(u_ptr);
}
private:
ETL_CONSTEXPR14 explicit not_null(const this_type& u_ptr_) ETL_NOEXCEPT ETL_DELETE;
ETL_CONSTEXPR14 not_null& operator=(const this_type& rhs) ETL_NOEXCEPT ETL_DELETE;
#if ETL_USING_CPP11
ETL_CONSTEXPR14 explicit not_null(this_type&& u_ptr_) ETL_NOEXCEPT = delete;
ETL_CONSTEXPR14 not_null& operator=(this_type&& rhs) ETL_NOEXCEPT = delete;
#endif
/// The underlying unique_ptr.
underlying_type u_ptr;
};

View File

@ -331,13 +331,15 @@ SOFTWARE.
#define ETL_ENUM_CLASS(name) enum class name
#define ETL_ENUM_CLASS_TYPE(name, type) enum class name : type
#define ETL_LVALUE_REF_QUALIFIER &
#define ETL_NOEXCEPT noexcept
#define ETL_NOEXCEPT_EXPR(...) noexcept(__VA_ARGS__)
#if ETL_USING_EXCEPTIONS
#define ETL_NOEXCEPT noexcept
#define ETL_NOEXCEPT_EXPR(...) noexcept(__VA_ARGS__)
#if ETL_NOT_USING_EXCEPTIONS
#define ETL_NOEXCEPT_IF_NO_THROW noexcept
#define ETL_NOEXCEPT_IF_NO_THROW_EXPR(...) noexcept(__VA_ARGS__)
#else
#define ETL_NOEXCEPT
#define ETL_NOEXCEPT_EXPR(...)
#define ETL_NOEXCEPT_IF_NO_THROW
#define ETL_NOEXCEPT_IF_NO_THROW_EXPR(...)
#endif
#else
#define ETL_CONSTEXPR

View File

@ -230,6 +230,7 @@ add_executable(etl_tests
test_multi_vector.cpp
test_murmur3.cpp
test_not_null_pointer.cpp
test_not_null_pointer_constexpr.cpp
test_not_null_unique_pointer.cpp
test_nth_type.cpp
test_numeric.cpp

View File

@ -31,15 +31,25 @@ SOFTWARE.
namespace
{
struct S
{
int x;
int get() const
{
return x;
}
};
SUITE(test_not_null_pointer)
{
//*************************************************************************
TEST(test_construct_from_non_null_pointer)
{
int value = 42;
int value = 123;
etl::not_null<int*> nn(&value);
CHECK_EQUAL(&value, nn.get());
CHECK_EQUAL(42, *nn);
CHECK_EQUAL(123, *nn);
}
//*************************************************************************
@ -79,49 +89,10 @@ namespace
CHECK_EQUAL(456, *nn2);
}
//*************************************************************************
TEST(test_underlying)
{
int value1 = 123;
etl::not_null<int*> nn1(&value1);
int* p = nn1.underlying();
CHECK_EQUAL(123, *p);
}
//*************************************************************************
TEST(test_underlying_const)
{
int value1 = 123;
const etl::not_null<int*> nn1(&value1);
const int* p = nn1.underlying();
CHECK_EQUAL(123, *p);
}
//*************************************************************************
TEST(test_unique_const)
{
using up_t = etl::unique_ptr<int>;
up_t up1(new int{ 123 });
const etl::not_null<up_t> nn(etl::move(up1));
const up_t& up2 = nn.underlying();
CHECK_EQUAL(123, *up2.get());
}
//*************************************************************************
TEST(test_implicit_conversion)
{
struct S
{
int x;
};
S s{77};
S s{123};
etl::not_null<S*> nn(&s);
S* raw = nn;
@ -131,17 +102,7 @@ namespace
//*************************************************************************
TEST(test_arrow_operator)
{
struct S
{
int x;
int get() const
{
return x;
}
};
S s{77};
S s{123};
etl::not_null<S*> nn(&s);
CHECK_EQUAL(s.x, nn->x);
@ -151,17 +112,7 @@ namespace
//*************************************************************************
TEST(test_dereference_operator)
{
struct S
{
int x;
int get() const
{
return x;
}
};
S s{77};
S s{123};
etl::not_null<S*> nn(&s);
CHECK_EQUAL(s.x, (*nn).x);

View File

@ -0,0 +1,154 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2025 John Wellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include "unit_test_framework.h"
#include "etl/not_null.h"
#if ETL_USING_CPP14
namespace
{
struct S
{
int x;
constexpr int get() const
{
return x;
}
};
//*************************************************************************
constexpr etl::not_null<const int*> CreateNotNullAssignFromPointer(const int* p1, const int* p2)
{
// Create a not_null pointer from a pointer.
etl::not_null<const int*> nn(p1);
// Assign a different pointer to the not_null.
nn = p2;
return nn;
}
//*************************************************************************
constexpr etl::not_null<const int*> CreateNotNullAssignFromNotNull(const int* p1, const int* p2)
{
// Create a not_null pointer from a pointer.
etl::not_null<const int*> nn1(p1);
etl::not_null<const int*> nn2(p2);
nn1 = nn2;
return nn1;
}
SUITE(test_not_null_pointer)
{
//*************************************************************************
TEST(test_construct_from_non_null_pointer)
{
static constexpr const int value = 123;
static constexpr etl::not_null<const int*> nn(&value);
static constexpr const int* p = nn.get();
static constexpr const int v = *nn;
CHECK_EQUAL(&value, p);
CHECK_EQUAL(123, v);
}
//*************************************************************************
TEST(test_copy_construct)
{
static constexpr const int value = 123;
static constexpr etl::not_null<const int*> nn1(&value);
static constexpr etl::not_null<const int*> nn2(nn1); // Copy constructor
static constexpr const int* p = nn2.get();
static constexpr const int v = *nn2;
CHECK_EQUAL(&value, p);
CHECK_EQUAL(123, v);
}
//*************************************************************************
TEST(test_assign_from_pointer)
{
static constexpr const int value1 = 123;
static constexpr const int value2 = 456;
static constexpr etl::not_null<const int*> nn(CreateNotNullAssignFromPointer(&value1, &value2));
CHECK_EQUAL(&value2, nn.get());
CHECK_EQUAL(456, *nn);
}
//*************************************************************************
TEST(test_assign_from_not_null)
{
static constexpr const int value1 = 123;
static constexpr const int value2 = 456;
static constexpr etl::not_null<const int*> nn(CreateNotNullAssignFromNotNull(&value1, &value2));
CHECK_EQUAL(&value2, nn.get());
CHECK_EQUAL(456, *nn);
}
//*************************************************************************
TEST(test_implicit_conversion)
{
static constexpr const S s{123};
static constexpr etl::not_null<const S*> nn(&s);
static constexpr const S* raw = nn;
CHECK_EQUAL(&s, raw);
}
//*************************************************************************
TEST(test_arrow_operator)
{
static constexpr const S s{123};
static constexpr etl::not_null<const S*> nn(&s);
static constexpr int x1 = nn->x;
static constexpr int x2 = nn->get();
CHECK_EQUAL(s.x, x1);
CHECK_EQUAL(s.get(), x2);
}
//*************************************************************************
TEST(test_dereference_operator)
{
static constexpr const S s{123};
static constexpr etl::not_null<const S*> nn(&s);
static constexpr int x1 = (*nn).x;
static constexpr int x2 = (*nn).get();
CHECK_EQUAL(s.x, x1);
CHECK_EQUAL(s.get(), x2);
}
};
}
#endif

View File

@ -54,44 +54,6 @@ namespace
CHECK_EQUAL(123, *nn.get());
}
//*************************************************************************
TEST(test_underlying)
{
using up_t = etl::unique_ptr<int>;
up_t up1(new int{ 123 });
etl::not_null<up_t> nn(etl::move(up1));
up_t up2 = etl::move(nn.underlying());
CHECK_EQUAL(123, *up2.get());
}
//*************************************************************************
TEST(test_underlying_const)
{
using up_t = etl::unique_ptr<int>;
up_t up1(new int{ 123 });
const etl::not_null<up_t> nn(etl::move(up1));
const up_t& up2 = etl::move(nn.underlying());
CHECK_EQUAL(123, *up2.get());
}
//*************************************************************************
TEST(test_move_construct)
{
using up_t = etl::unique_ptr<int>;
up_t up(new int{ 123 });
etl::not_null<up_t> nn1(etl::move(up));
etl::not_null<up_t> nn2(etl::move(nn1)); // Move constructor
CHECK_TRUE(nn1.get() == nullptr);
CHECK_EQUAL(123, *nn2.get());
CHECK_EQUAL(123, *nn2);
}
//*************************************************************************
TEST(test_assign_from_unique_ptr)
{
@ -108,22 +70,6 @@ namespace
CHECK_EQUAL(456, *nn1.get());
}
//*************************************************************************
TEST(test_assign_from_not_null)
{
using up_t = etl::unique_ptr<int>;
up_t up1(new int{ 123 });
etl::not_null<up_t> nn1(etl::move(up1));
up_t up2(new int{ 456 });
etl::not_null<up_t> nn2(etl::move(up2));
nn1 = etl::move(nn2);
CHECK_TRUE(nn2.get() == nullptr);
CHECK_EQUAL(456, *nn1.get());
}
//*************************************************************************
TEST(test_implicit_conversion)
{

View File

@ -38,3 +38,25 @@
#define CHECK_ARRAY_EQUAL
#define CHECK_CLOSE
#define CHECK_THROW
// Hint files help the Visual Studio IDE interpret Visual C++ identifiers
// such as names of functions and macros.
// For more information see https://go.microsoft.com/fwlink/?linkid=865984
#define ETL_NOEXCEPT_IF_NO_THROW
// Hint files help the Visual Studio IDE interpret Visual C++ identifiers
// such as names of functions and macros.
// For more information see https://go.microsoft.com/fwlink/?linkid=865984
#define ETL_NOEXCEPT
// Hint files help the Visual Studio IDE interpret Visual C++ identifiers
// such as names of functions and macros.
// For more information see https://go.microsoft.com/fwlink/?linkid=865984
#define ETL_ASSERT(b, e)
#define ETL_ASSERT(b, e) {if (!(b)) ETL_UNLIKELY {etl::error_handler::error((e)); throw((e));}}
#define ETL_ASSERT(b, e) {if (!(b)) ETL_UNLIKELY {throw((e));}}
#define ETL_ASSERT(b, e) {if (!(b)) ETL_UNLIKELY {etl::error_handler::error((e));}}
#define ETL_ASSERT(b, e) assert((b))
#define ETL_ASSERT(b, e) {if (!(b)) ETL_UNLIKELY {etl::private_error_handler::assert_handler<0>::assert_function_ptr((e));}}
// Hint files help the Visual Studio IDE interpret Visual C++ identifiers
// such as names of functions and macros.
// For more information see https://go.microsoft.com/fwlink/?linkid=865984
#define ETL_ERROR(e) (e(__FILE__, __LINE__))
#define ETL_ERROR(e) (e("", __LINE__))

View File

@ -9492,6 +9492,7 @@
<ClCompile Include="..\test_message.cpp" />
<ClCompile Include="..\test_message_broker.cpp" />
<ClCompile Include="..\test_not_null_pointer.cpp" />
<ClCompile Include="..\test_not_null_pointer_constexpr.cpp" />
<ClCompile Include="..\test_not_null_unique_pointer.cpp" />
<ClCompile Include="..\test_poly_span_dynamic_extent.cpp" />
<ClCompile Include="..\test_poly_span_fixed_extent.cpp" />

View File

@ -1521,6 +1521,9 @@
<ClInclude Include="..\..\include\etl\callback_timer_deferred_locked.h">
<Filter>ETL\Frameworks</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\not_null.h">
<Filter>ETL\Utilities</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\test_string_char.cpp">
@ -3695,6 +3698,9 @@
<ClCompile Include="..\syntax_check\not_null.h.t.cpp">
<Filter>Tests\Syntax Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\test_not_null_pointer_constexpr.cpp">
<Filter>Tests\Misc</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\..\library.properties">