Skip to content

Commit

Permalink
feat: make all hal::Can::Id functions constexpr and add static assert…
Browse files Browse the repository at this point in the history
… tests (#803)

* feat: make all hal::Can::Id functions constexpr and add static assert tests

* chore: separate implementation from declaration

* Update hal/interfaces/Can.hpp
  • Loading branch information
daantimmer authored Jan 8, 2025
1 parent 6284b6f commit 6184a66
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 86 deletions.
1 change: 0 additions & 1 deletion hal/interfaces/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ target_sources(hal.interfaces PRIVATE
AsyncGpio.cpp
AsyncGpio.hpp
BackupRam.hpp
Can.cpp
Can.hpp
CommunicationConfigurator.hpp
DigitalToAnalogPin.hpp
Expand Down
38 changes: 0 additions & 38 deletions hal/interfaces/Can.cpp

This file was deleted.

72 changes: 55 additions & 17 deletions hal/interfaces/Can.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,36 @@

#include "infra/util/BoundedVector.hpp"
#include "infra/util/Function.hpp"
#include <cassert>
#include <cstdint>

namespace hal
{
class Can
{
public:
class Id
class [[nodiscard]] Id
{
public:
static constexpr Id Create11BitId(uint32_t id)
{
return Can::Id(id);
}
static constexpr Id Create11BitId(uint32_t id);
static constexpr Id Create29BitId(uint32_t id);

static constexpr Id Create29BitId(uint32_t id)
{
return Can::Id(id | indicator29Bit);
}
[[nodiscard]] constexpr bool Is11BitId() const;
[[nodiscard]] constexpr bool Is29BitId() const;

bool Is11BitId() const;
bool Is29BitId() const;
[[nodiscard]] constexpr uint32_t Get11BitId() const;
[[nodiscard]] constexpr uint32_t Get29BitId() const;

uint32_t Get11BitId() const;
uint32_t Get29BitId() const;

bool operator==(const Id& other) const;
bool operator!=(const Id& other) const;
[[nodiscard]] constexpr bool operator==(const Id& other) const;
[[nodiscard]] constexpr bool operator!=(const Id& other) const;

private:
constexpr explicit Id(uint32_t id)
: id(id)
{}

private:
static const uint32_t indicator29Bit = static_cast<uint32_t>(1) << 31;
static constexpr uint32_t indicator29Bit{ 1u << 31 };

uint32_t id;
};
Expand All @@ -56,6 +50,50 @@ namespace hal
virtual void SendData(Id id, const Message& data, const infra::Function<void(bool success)>& actionOnCompletion) = 0;
virtual void ReceiveData(const infra::Function<void(Id id, const Message& data)>& receivedAction) = 0;
};

//// Implementation ////

constexpr Can::Id Can::Id::Create11BitId(uint32_t id)
{
return Can::Id(id);
}

constexpr Can::Id Can::Id::Create29BitId(uint32_t id)
{
return Can::Id(id | indicator29Bit);
}

constexpr bool Can::Id::Is11BitId() const
{
return (id & indicator29Bit) == 0;
}

constexpr bool Can::Id::Is29BitId() const
{
return !Is11BitId();
}

constexpr uint32_t Can::Id::Get11BitId() const
{
assert(Is11BitId());
return id;
}

constexpr uint32_t Can::Id::Get29BitId() const
{
assert(Is29BitId());
return id ^ indicator29Bit;
}

constexpr bool Can::Id::operator==(const Id& other) const
{
return id == other.id;
}

constexpr bool Can::Id::operator!=(const Id& other) const
{
return !(*this == other);
}
}

#endif
79 changes: 49 additions & 30 deletions hal/interfaces/test/TestCan.cpp
Original file line number Diff line number Diff line change
@@ -1,46 +1,65 @@
#include "hal/interfaces/Can.hpp"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

static_assert(hal::Can::Id::Create11BitId(0).Is11BitId());
static_assert(!hal::Can::Id::Create11BitId(0).Is29BitId());
static_assert(hal::Can::Id::Create11BitId(0).Get11BitId() == 0);

static_assert(!hal::Can::Id::Create29BitId(0).Is11BitId());
static_assert(hal::Can::Id::Create29BitId(0).Is29BitId());
static_assert(hal::Can::Id::Create29BitId(0).Get29BitId() == 0);

static_assert(hal::Can::Id::Create11BitId(0) == hal::Can::Id::Create11BitId(0));
static_assert(hal::Can::Id::Create11BitId(0) != hal::Can::Id::Create11BitId(1));
static_assert(hal::Can::Id::Create11BitId(0) != hal::Can::Id::Create29BitId(0));

static_assert(hal::Can::Id::Create29BitId(2) == hal::Can::Id::Create29BitId(2));
static_assert(hal::Can::Id::Create29BitId(2) != hal::Can::Id::Create29BitId(1));
static_assert(hal::Can::Id::Create29BitId(2) != hal::Can::Id::Create11BitId(2));

TEST(CanTest, generate_11_bit_id)
{
auto id = hal::Can::Id::Create11BitId(0);
const auto id = hal::Can::Id::Create11BitId(0);

EXPECT_TRUE(id.Is11BitId());
EXPECT_EQ(0, id.Get11BitId());
EXPECT_THAT(id.Is11BitId(), testing::IsTrue());
EXPECT_THAT(id.Is29BitId(), testing::IsFalse());
EXPECT_THAT(id.Get11BitId(), testing::Eq(0));
}

TEST(CanTest, generate_29_bit_id)
{
auto id = hal::Can::Id::Create29BitId(0);
const auto id = hal::Can::Id::Create29BitId(0);

EXPECT_TRUE(id.Is29BitId());
EXPECT_EQ(0, id.Get29BitId());
EXPECT_THAT(id.Is29BitId(), testing::IsTrue());
EXPECT_THAT(id.Is11BitId(), testing::IsFalse());
EXPECT_THAT(id.Get29BitId(), testing::Eq(0));
}

TEST(CanTest, test_equality_mixed)
{
auto id11_0 = hal::Can::Id::Create11BitId(0);
auto id11_1 = hal::Can::Id::Create11BitId(1);
auto id29_0 = hal::Can::Id::Create29BitId(0);
auto id29_1 = hal::Can::Id::Create29BitId(1);

EXPECT_TRUE(id11_0 == hal::Can::Id::Create11BitId(0));
EXPECT_TRUE(id11_0 != id11_1);
EXPECT_TRUE(id11_0 != id29_0);
EXPECT_TRUE(id11_0 != id29_1);

EXPECT_TRUE(id11_1 != id11_0);
EXPECT_TRUE(id11_1 == hal::Can::Id::Create11BitId(1));
EXPECT_TRUE(id11_1 != id29_0);
EXPECT_TRUE(id11_1 != id29_1);

EXPECT_TRUE(id29_0 != id11_0);
EXPECT_TRUE(id29_0 != id11_1);
EXPECT_TRUE(id29_0 == hal::Can::Id::Create29BitId(0));
EXPECT_TRUE(id29_0 != id29_1);

EXPECT_TRUE(id29_1 != id11_0);
EXPECT_TRUE(id29_1 != id11_1);
EXPECT_TRUE(id29_1 != id29_0);
EXPECT_TRUE(id29_1 == hal::Can::Id::Create29BitId(1));
const auto id11_0 = hal::Can::Id::Create11BitId(0);
const auto id11_1 = hal::Can::Id::Create11BitId(1);
const auto id29_0 = hal::Can::Id::Create29BitId(0);
const auto id29_1 = hal::Can::Id::Create29BitId(1);

EXPECT_THAT(id11_0, testing::Eq(hal::Can::Id::Create11BitId(0)));
EXPECT_THAT(id11_0, testing::Ne(id11_1));
EXPECT_THAT(id11_0, testing::Ne(id29_0));
EXPECT_THAT(id11_0, testing::Ne(id29_1));

EXPECT_THAT(id11_1, testing::Ne(id11_0));
EXPECT_THAT(id11_1, testing::Eq(hal::Can::Id::Create11BitId(1)));
EXPECT_THAT(id11_1, testing::Ne(id29_0));
EXPECT_THAT(id11_1, testing::Ne(id29_1));

EXPECT_THAT(id29_0, testing::Ne(id11_0));
EXPECT_THAT(id29_0, testing::Ne(id11_1));
EXPECT_THAT(id29_0, testing::Eq(hal::Can::Id::Create29BitId(0)));
EXPECT_THAT(id29_0, testing::Ne(id29_1));

EXPECT_THAT(id29_1, testing::Ne(id11_0));
EXPECT_THAT(id29_1, testing::Ne(id11_1));
EXPECT_THAT(id29_1, testing::Ne(id29_0));
EXPECT_THAT(id29_1, testing::Eq(hal::Can::Id::Create29BitId(1)));
}

0 comments on commit 6184a66

Please sign in to comment.