Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass Align template param; unit test it. #106

Merged
merged 4 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
138 changes: 87 additions & 51 deletions cetlvast/suites/unittest/test_any.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,72 @@ using cetl::any;
using cetl::any_cast;
using cetl::in_place_type_t;

/// HELPERS ---------------------------------------------------------------------------------------------------------

struct TestCopyable
{
int value_ = 0;

TestCopyable() = default;
TestCopyable(const TestCopyable& other)
{
value_ = other.value_ + 10;
}

TestCopyable& operator=(const TestCopyable& other)
{
value_ = other.value_ + 10;
return *this;
}
};

struct TestMovableOnly
{
int value_ = 0;

TestMovableOnly() = default;
TestMovableOnly(const TestMovableOnly& other) = delete;
TestMovableOnly(TestMovableOnly&& other) noexcept
{
value_ = other.value_ + 1;
}
~TestMovableOnly() = default;

TestMovableOnly& operator=(const TestMovableOnly& other) = delete;
TestMovableOnly& operator=(TestMovableOnly&& other) noexcept
{
value_ = other.value_ + 1;
return *this;
}
};

struct TestCopyableAndMovable
{
int value_ = 0;

TestCopyableAndMovable() = default;
TestCopyableAndMovable(const TestCopyableAndMovable& other)
{
value_ = other.value_ + 10;
}
TestCopyableAndMovable(TestCopyableAndMovable&& other) noexcept
{
value_ = other.value_ + 1;
}
~TestCopyableAndMovable() = default;

TestCopyableAndMovable& operator=(const TestCopyableAndMovable& other)
{
value_ = other.value_ + 10;
return *this;
}
TestCopyableAndMovable& operator=(TestCopyableAndMovable&& other) noexcept
{
value_ = other.value_ + 1;
return *this;
}
};

/// TESTS -----------------------------------------------------------------------------------------------------------

TEST(test_any, cppref_example)
Expand All @@ -39,19 +105,27 @@ TEST(test_any, cppref_example)
TEST(test_any, ctor_1_default)
{
EXPECT_FALSE((any<0>{}.has_value()));
EXPECT_EQ(alignof(std::max_align_t), alignof(any<0>));
EXPECT_FALSE((any<0, false>{}.has_value()));
EXPECT_FALSE((any<0, false, true>{}.has_value()));
EXPECT_FALSE((any<0, true, false>{}.has_value()));
EXPECT_FALSE((any<0, true, true, 0>{}.has_value()));
EXPECT_EQ(alignof(std::max_align_t), alignof(any<0, true, true, 0>));

EXPECT_FALSE((any<1>{}.has_value()));
EXPECT_EQ(alignof(std::max_align_t), alignof(any<1>));
EXPECT_FALSE((any<1, false>{}.has_value()));
EXPECT_FALSE((any<1, false, true>{}.has_value()));
EXPECT_FALSE((any<1, true, false>{}.has_value()));
EXPECT_FALSE((any<1, true, false, 1>{}.has_value()));
EXPECT_EQ(256, alignof(any<1, true, true, 256>));

EXPECT_FALSE((any<13>{}.has_value()));
EXPECT_EQ(sizeof(std::max_align_t), alignof(any<13>));
EXPECT_FALSE((any<13, false>{}.has_value()));
EXPECT_FALSE((any<13, false, true>{}.has_value()));
EXPECT_FALSE((any<13, true, false>{}.has_value()));
EXPECT_EQ(256, alignof(any<13, true, true, 256>));
}

TEST(test_any, ctor_2_copy)
Expand All @@ -69,23 +143,13 @@ TEST(test_any, ctor_2_copy)

// Copyable
{
struct TestCopyable
{
int value_ = 0;

TestCopyable() = default;
TestCopyable(const TestCopyable& other)
{
value_ = other.value_ + 1;
}
};
using uut = any<sizeof(TestCopyable)>;

const uut src{TestCopyable{}};
const uut dst{src};

EXPECT_EQ(1, *any_cast<int>(&src));
EXPECT_EQ(2, *any_cast<int>(&dst));
EXPECT_EQ(10, *any_cast<int>(&src));
EXPECT_EQ(20, *any_cast<int>(&dst));
}
}

Expand All @@ -102,26 +166,11 @@ TEST(test_any, ctor_3_move)
EXPECT_EQ(42, *any_cast<int>(&dst));
}

// Movable
// Copyable and Movable
{
struct TestMovable
{
int value_ = 0;
using uut = any<sizeof(TestCopyableAndMovable)>;

TestMovable() = default;
TestMovable(const TestMovable& other)
{
value_ = other.value_ + 10;
}
TestMovable(TestMovable&& other) noexcept
{
value_ = other.value_ + 1;
}
~TestMovable() = default;
};
using uut = any<sizeof(TestMovable)>;

uut src{TestMovable{}};
uut src{TestCopyableAndMovable{}};
EXPECT_TRUE(src.has_value());

const uut dst{std::move(src)};
Expand All @@ -133,25 +182,10 @@ TEST(test_any, ctor_3_move)

TEST(test_any, ctor_4_move_value)
{
struct TestMovable
{
int value_ = 0;

TestMovable() = default;
TestMovable(const TestMovable& other)
{
value_ = other.value_ + 10;
}
TestMovable(TestMovable&& other) noexcept
{
value_ = other.value_ + 1;
}
~TestMovable() = default;
};
using uut = any<sizeof(TestMovable)>;
using uut = any<sizeof(TestCopyableAndMovable)>;

TestMovable src{};
const uut dst{std::move(src)};
TestCopyableAndMovable src{};
const uut dst{std::move(src)};
EXPECT_TRUE(dst.has_value());
EXPECT_EQ(1, *any_cast<int>(&dst));
}
Expand Down Expand Up @@ -302,7 +336,7 @@ TEST(test_any, make_any_1)
EXPECT_EQ(42, *any_cast<int>(&test));
}

TEST(test_any, make_any_2_ilist)
TEST(test_any, make_any_2_list)
{
struct TestType
{
Expand Down Expand Up @@ -424,16 +458,18 @@ TEST(test_any, any_cast_4_const_ptr)
EXPECT_FALSE((any_cast<char, uut>(nullptr)));
}

TEST(test_any, any_cast_5_non_const_ptr)
TEST(test_any, any_cast_5_non_const_ptr_with_custom_alignment)
{
using uut = any<sizeof(char)>;
constexpr std::size_t alignment = 4096;
using uut = any<sizeof(char), true, true, alignment>;

uut src{'Y'};

auto char_ptr = any_cast<char>(&src);
static_assert(std::is_same<char*, decltype(char_ptr)>::value, "");
EXPECT_TRUE(char_ptr);
EXPECT_EQ('Y', *char_ptr);
EXPECT_EQ(0, reinterpret_cast<intptr_t>(char_ptr) & static_cast<std::intptr_t>(alignment - 1));

EXPECT_FALSE((any_cast<char, uut>(nullptr)));
}
Expand Down
31 changes: 17 additions & 14 deletions include/cetl/any.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,21 @@ namespace cetl
{

// Forward declarations
template <std::size_t Footprint, bool Copyable, bool Movable>
template <std::size_t Footprint, bool Copyable, bool Movable, std::size_t Align>
class any;

namespace detail
{

// Move policy.
template <std::size_t Footprint, bool Copyable, bool Movable>
template <std::size_t Footprint, bool Copyable, bool Movable, std::size_t Align>
struct base_move;

// Copy policy.
template <std::size_t Footprint, bool Copyable>
template <std::size_t Footprint, bool Copyable, std::size_t Align>
struct base_copy;

template <std::size_t Footprint, std::size_t Align = sizeof(std::max_align_t)>
template <std::size_t Footprint, std::size_t Align>
struct base_storage
{
// We need to align the buffer to the given value (maximum alignment by default).
Expand All @@ -43,8 +43,8 @@ struct base_storage
};

// Movable case.
template <std::size_t Footprint, bool Copyable>
struct base_move<Footprint, Copyable, true> : base_copy<Footprint, Copyable>
template <std::size_t Footprint, bool Copyable, std::size_t Align>
struct base_move<Footprint, Copyable, true, Align> : base_copy<Footprint, Copyable, Align>
{
public:
constexpr base_move() = default;
Expand All @@ -53,8 +53,8 @@ struct base_move<Footprint, Copyable, true> : base_copy<Footprint, Copyable>
};

// Non-movable case.
template <std::size_t Footprint, bool Copyable>
struct base_move<Footprint, Copyable, false> : base_copy<Footprint, Copyable>
template <std::size_t Footprint, bool Copyable, std::size_t Align>
struct base_move<Footprint, Copyable, false, Align> : base_copy<Footprint, Copyable, Align>
{
public:
constexpr base_move() = default;
Expand All @@ -63,8 +63,8 @@ struct base_move<Footprint, Copyable, false> : base_copy<Footprint, Copyable>
};

// Copyable case.
template <std::size_t Footprint>
struct base_copy<Footprint, true> : base_storage<Footprint>
template <std::size_t Footprint, std::size_t Align>
struct base_copy<Footprint, true, Align> : base_storage<Footprint, Align>
{
public:
constexpr base_copy() = default;
Expand All @@ -73,8 +73,8 @@ struct base_copy<Footprint, true> : base_storage<Footprint>
};

// Non-copyable case.
template <std::size_t Footprint>
struct base_copy<Footprint, false> : base_storage<Footprint>
template <std::size_t Footprint, std::size_t Align>
struct base_copy<Footprint, false, Align> : base_storage<Footprint, Align>
{
public:
constexpr base_copy() = default;
Expand All @@ -101,8 +101,11 @@ enum class action

} // namespace detail

template <std::size_t Footprint, bool Copyable = true, bool Movable = Copyable>
class any : private detail::base_move<Footprint, Copyable, Movable>
template <std::size_t Footprint,
bool Copyable = true,
bool Movable = Copyable,
std::size_t Align = alignof(std::max_align_t)>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
std::size_t Align = alignof(std::max_align_t)>
std::size_t Alignment= alignof(std::max_align_t)>

class any : private detail::base_move<Footprint, Copyable, Movable, Align>
{
public:
constexpr any() noexcept = default;
Expand Down