-
Notifications
You must be signed in to change notification settings - Fork 5
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
ConstantIterator #62
base: master
Are you sure you want to change the base?
ConstantIterator #62
Conversation
AntonReinhard
commented
Jan 4, 2022
- Add ConstantIterator class
- Yields the same value it was initialized with every time
- Add testing for the class
344b3ef
to
0951632
Compare
|
||
using namespace vikunja::mem::iterator; | ||
|
||
TEMPLATE_TEST_CASE("Test Constant Iterator", "", int, double, uint64_t) |
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 add also a test case to integ/transform
. I think int operator()(int i) { return 2*i;}
is a good functor for certificate the result (sum = size * 2 * constant
).
@bernhardmgruber Can you please review it. |
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 the whole point of this iterator is to just return the same value whenever dereferences, I see no need to store an index. Then all iterator functions that move the iterator become noops. When do you need the index of the iterator?
You can probably make all member functions of ConstantIterator
constexpr
and noexcept
.
#if defined __has_include | ||
# if __has_include(<version>) | ||
# include <version> | ||
# endif | ||
# if __has_include(<compare>) | ||
# include <compare> | ||
# if defined(__cpp_lib_three_way_comparison) && defined(__cpp_impl_three_way_comparison) | ||
# define USESPACESHIP | ||
# endif | ||
# endif | ||
#endif |
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.
alpaka moved to C++17 recently. So maybe vikunja should be on C++17 as well. In this case you would not need the #if defined __has_include
.
Furthermore, it seems you require only the language feature and not the library feature. In this case you can just test for __cpp_impl_three_way_comparison
which is predefined by the compiler and does not require including the <version>
header. See: https://en.cppreference.com/w/cpp/feature_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.
After some discussion today, we decided to move to C++17. I want to provide a PR with the necessary changes this week.
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.
Furthermore, it seems you require only the language feature and not the library feature. In this case you can just test for
__cpp_impl_three_way_comparison
You're completely right, somehow I was under the impression that you always needed the header
/** | ||
* @brief Spaceship operator for comparisons | ||
*/ | ||
NODISCARD ALPAKA_FN_INLINE auto operator<=>(const ConstantIterator& other) const noexcept = default; |
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.
Such comments don't increase clarity of the code and only add noise. Try to avoid comments for the sake of comments, if they don't add any additional information the code is not already giving.
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.
There is also the philosophy to have a doxygen comment for every function, even if it's fairly (or very) obvious what the function does. But I can also remove them if that's not the case for this project. Should I also remove them for the other straight forward arithmetic operators then?
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.
To be honest, there is no real guide for the doxygen yet. The student who started this project, did it in some way. I don't believe, that he got some feedback. I want to overwork this in the near future, see #65 . But Bernhard is right, the function is already defined by the concept iterator
. Therefore the one line which explains the obvious is not necessary.
NODISCARD ALPAKA_FN_INLINE bool operator>(const ConstantIterator& other) const noexcept | ||
{ | ||
if(v > other.v) | ||
return true; | ||
if(v < other.v) | ||
return false; | ||
return index > other.index; | ||
} |
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.
When implementing comparison operators, you usually only implement operator<
and operator==
. The rest should be based on those:
NODISCARD ALPAKA_FN_INLINE bool operator>(const ConstantIterator& other) const noexcept | |
{ | |
if(v > other.v) | |
return true; | |
if(v < other.v) | |
return false; | |
return index > other.index; | |
} | |
NODISCARD ALPAKA_FN_INLINE bool operator>(const ConstantIterator& other) const noexcept | |
{ | |
return other < *this; | |
} |
This way you can avoid accidentially only defining a partial order for your type. Or inconsistent comparions (e.g. a < b
and a > b
at the same time).
Applies to other operators below.
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 know this can be done and reduces the probability to make mistakes, but I was trying to be explicit so I was sure the compiler wouldn't add unnecessary function calls. But I can change it anyways, if you think that this is unnecessary
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.
Compiler inlining heuristics are quite good! I am certain, the compiler would inline the delegation to operator<
inside operator>
.
#pragma endregion comparisonoperators | ||
|
||
private: | ||
const DataType v; |
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.
By making v
const
, your type is not movable (which might not be a problem), but also not swapable. I would avoid it, but I leave the choice to you.
The index is required for begin and end pointer: ConstantIterator c_begin(10);
ConstantIterator c_end = c_begin + 4;
for(; c_begin < c_end; ++c_begin){
std::cout << *c_begin << " "; // 10 10 10 10
} Do you have a better idea? |
No, makes perfect sense now :D Without the index you would have an infinite range. |
@AntonReinhard Can you please rebase to the current master. I removed the C++ 14 support. New default is C++ 17. |
699e6e2
to
a25943f
Compare
Ah, I knew you had to include for the spaceship operator: https://godbolt.org/z/soa55sP73 |
1348e97
to
471ec41
Compare
f1662d5
to
a071d4a
Compare
Two points:
Can you execute your results on a local system or Taurus? If not, we have a Quadro V100 in our dev system. I can execute the benchmarks and send you the results. |
By the way, I was aware about the wrong results on the serial backend in the reduce benchmark. I think, it is a precession problem of float and the many summations on a single value. But I had no time yet to investigate this. |
78e2bf1
to
d7f40b1
Compare
Co-authored-by: Bernhard Manfred Gruber <[email protected]>
047fb57
to
b6bcef7
Compare