-
Notifications
You must be signed in to change notification settings - Fork 403
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
Iox #86 introduce cxx function ref #124
Iox #86 introduce cxx function ref #124
Conversation
Signed-off-by: Hoinkis Simon (CC-AD/ESW1) <simon.hoinkis2@de.bosch.com>
Signed-off-by: Hoinkis Simon (CC-AD/ESW1) <simon.hoinkis2@de.bosch.com>
…ction_ref Signed-off-by: Hoinkis Simon (CC-AD/ESW1) <simon.hoinkis2@de.bosch.com>
Signed-off-by: Hoinkis Simon (CC-AD/ESW1) <simon.hoinkis2@de.bosch.com>
Signed-off-by: Hoinkis Simon (CC-AD/ESW1) <simon.hoinkis2@de.bosch.com>
…nction_ref Signed-off-by: Hoinkis Simon (CC-AD/ESW1) <simon.hoinkis2@de.bosch.com>
… case and add more test todo's Signed-off-by: Hoinkis Simon (CC-AD/ESW1) <simon.hoinkis2@de.bosch.com>
Signed-off-by: Hoinkis Simon (CC-AD/ESW1) <simon.hoinkis2@de.bosch.com>
Signed-off-by: Hoinkis Simon (CC-AD/ESW1) <simon.hoinkis2@de.bosch.com>
Signed-off-by: Hoinkis Simon (CC-AD/ESW1) <simon.hoinkis2@de.bosch.com>
Signed-off-by: Hoinkis Simon (CC-AD/ESW1) <simon.hoinkis2@de.bosch.com>
Signed-off-by: Hoinkis Simon (CC-AD/ESW1) <simon.hoinkis2@de.bosch.com>
Signed-off-by: Hoinkis Simon (CC-AD/ESW1) <simon.hoinkis2@de.bosch.com>
…or function_ref Signed-off-by: Hoinkis Simon (CC-AD/ESW1) <simon.hoinkis2@de.bosch.com>
Signed-off-by: Hoinkis Simon (CC-AD/ESW1) <simon.hoinkis2@de.bosch.com>
… explicit overloads for move assignment operator Signed-off-by: Hoinkis Simon (CC-AD/ESW1) <simon.hoinkis2@de.bosch.com>
Signed-off-by: Hoinkis Simon (CC-AD/ESW1) <simon.hoinkis2@de.bosch.com>
Signed-off-by: Hoinkis Simon (CC-AD/ESW1) <simon.hoinkis2@de.bosch.com>
|
||
public: | ||
/// @brief Creates an empty function_ref | ||
function_ref() noexcept |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not really a big fan of this. optional<function_ref> would be better in my point of view, but it seems the decision was to do it this way
on the other hand, you would result in the same, invalid object after a move operation
function_ref<int()> sut1(lambda); | ||
function_ref<int()> sut2{sut1}; | ||
EXPECT_TRUE(sut2); | ||
EXPECT_THAT(sut2(), Eq(42)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please use a constexpr instead of magic numbers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Magic numbers are magic 🦄 For small tests I prefer to omit the extra variable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I disagree, but not enough to prevent this merge
it should become muscle memory and that only happens if you do it all the time ;)
TEST_F(function_refTest, CreateWithStdBind) | ||
{ | ||
function_ref<int()> sut(std::bind(&function_refTest::foobar, this)); | ||
EXPECT_THAT(sut(), Eq(4273)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no magic numbers please
|
||
bool operator==(const ComplexType& rhs) const | ||
{ | ||
if (a == rhs.a && b == rhs.b && c == rhs.c) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not write simply:
return ( a == rhs.a && b == rhs.b && c == rhs.c);
This would save you 7 lines and lines these days are very expensive ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that's boring ... on the other side, Walter E. Brown knows much more interesting ways to return true ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it is test code I don't care about LoC, but prefer to make it more readable :-) For everyone interested in the brilliant talk, here's the link: https://www.youtube.com/watch?v=OAmWHmwlMwI
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I disagree. How does it make your code more readable when you just add more lines?
The first line ( a == rhs.a && b == rhs.b && c == rhs.c)
have to be understood either way and with your approach you have 6 more lines to understood
Signed-off-by: Hoinkis Simon (CC-AD/ESW1) <simon.hoinkis2@de.bosch.com>
Signed-off-by: Hoinkis Simon (CC-AD/ESW1) <simon.hoinkis2@de.bosch.com>
Signed-off-by: Hoinkis Simon (CC-AD/ESW1) <simon.hoinkis2@de.bosch.com>
Signed-off-by: Hoinkis Simon (CC-AD/ESW1) <simon.hoinkis2@de.bosch.com>
if (!m_target) | ||
{ | ||
// Callable was called without user having assigned one beforehand | ||
std::cerr << "Empty function_ref invoked" << std::endl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we have to come up with a strategy whether is is cool to directly use std::cerr or if we should use our logger. As this is not the first affected module, this PR is fine so far but I created a new issue to address this question #130
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the idea was to use cout, clog and cerr in the utils and then let the logger capture that and map it to a LogInfo, LogWarn and LogError ... unfortunatelly there was not yet time to do this
EXPECT_TRUE(sut); | ||
} | ||
|
||
TEST_F(function_refTest, CreateValidByAssignResultEqual) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't this also be CallValid...
EXPECT_THAT(sut(), Eq(7253)); | ||
} | ||
|
||
TEST_F(function_refTest, CreateValidByCopyConstructResultEqual) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
again, CallValid...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll rename it just for you <3
auto lambda = []() -> int { return 3527; }; | ||
function_ref<int()> sut1{lambda}; | ||
function_ref<int()> sut2(sut1); | ||
EXPECT_TRUE(sut2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please make this an ASSERT_TRUE, else the whole test will terminate in the next call
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will be done in follow-up #131
auto lambda = []() -> int { return 123; }; | ||
function_ref<int()> sut1{lambda}; | ||
function_ref<int()> sut2{std::move(sut1)}; | ||
EXPECT_TRUE(sut2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please make an ASSERT_THAT, else the access to sut2 further down might terminate the whole test
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, will be done in #131
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove unnecessary comments.
Add some more tags to your comments.
/// @brief Creates an empty function_ref | ||
function_ref() noexcept; | ||
|
||
/// @brief D'tor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please write a meaningful comment or remove it. That this is the default destructor is obvious.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Touché
/// @brief D'tor | ||
~function_ref() noexcept = default; | ||
|
||
/// @brief Copy c'tor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we do not need to document compiler generated code. This is the default copy constructor which is already clearly declared.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your Karma point +1 ;)
/// @brief Copy c'tor | ||
function_ref(const function_ref&) noexcept = default; | ||
|
||
/// @brief Copy assignment operator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove unnecessary comment
template <typename CallableType, typename = EnableIfNotFunctionRef<CallableType>> | ||
function_ref(CallableType&& callable) noexcept; | ||
|
||
/// @brief Moves a function_ref |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove unnecessary comment!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
/// @brief Raw pointer of the callable | ||
void* m_target{nullptr}; | ||
|
||
/// @brief Function pointer to the callable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, remove the comment since the name is clearly understandable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed
/// @brief Checks whether a valid target is contained | ||
explicit operator bool() const noexcept; | ||
|
||
void swap(function_ref& rhs) noexcept; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function is not documented...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added documentation
@@ -0,0 +1,105 @@ | |||
// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
||
bool operator==(const ComplexType& rhs) const | ||
{ | ||
if (a == rhs.a && b == rhs.b && c == rhs.c) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I disagree. How does it make your code more readable when you just add more lines?
The first line ( a == rhs.a && b == rhs.b && c == rhs.c)
have to be understood either way and with your approach you have 6 more lines to understood
/// fuu([]{ doSomething(); }); | ||
/// | ||
/// // Usage with l-values | ||
/// // Pitfall: Ensure that lifetime of callable suits the point in time of calling callback() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This pitfall has to be stated in the doxygen docu in the method
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
using EnableIfNotFunctionRef = typename std::enable_if<!std::is_same<std::decay<T>, function_ref>::value>::type; | ||
|
||
public: | ||
/// @brief Creates an empty function_ref |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should maybe state the default constructor creates a function_ref in an invalid state and operator bool() returns false
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added
Signed-off-by: Hoinkis Simon (CC-AD/ESW1) <simon.hoinkis2@de.bosch.com>
Resolves #86