-
Notifications
You must be signed in to change notification settings - Fork 118
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
All tests now pass under latest MSVC #47
All tests now pass under latest MSVC #47
Conversation
- Currently on MSVC cl 19.15.26726, only 5/34 test files compile and pass tests
…alue (but kept tests using old syntax). - Fixed bug that operators * and -> should be const in IteratorIterator as they do not modify the iterator. - Changed name of template parameter from Container to T in iterator_type, because of a bug in MSVC. - Used an explicit decltype, instead of decltype(auto), in TupleStarMapper::IteratorData::get_and_call_with_tuple because MSVC was not able to deduce it. - Fixed bug in filterfalse_examples where <string> was not included. Result with MSVC: - All tests pass and examples are running, in release build. - 4/34 test files fail in debug, because of STL assertion failure.
…rbegin()-1 was used but is undefined behavior (see C++17 [bidirectional.iterators] and [random.access.iterators]). - Fixed incorrect test in test_sorted that was not checking the result of the comparision, but is disabled for now as it compares iterators on different containers, which is undefined behavior (see C++17 [forward.iterators]¶2). - Now all tests are passing with MSVC.
…ere it would slightly change tests) - Replaced std::all_of and any_of by fold expressions
…es the types used in the tests)
There's a lot here that I can easily accept, some other things I need to take a closer look at to see if there's any cases that they might break. I'm gonna need some time here but I appreciate your effort, thank you |
@@ -32,15 +32,15 @@ namespace iter { | |||
|
|||
template <typename Container> | |||
using IteratorWrapper = typename IteratorWrapperImplType<Container, | |||
std::is_same<impl::iterator_type<Container>, | |||
impl::iterator_end_type<Container>>{}>::type; | |||
std::is_same_v<impl::iterator_type<Container>, |
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.
is this actually required for msvc?
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.
Yes, it is. I should report the bug in msvc. It gives an "error C2512: 'std::is_same<Ts,Ts>': no appropriate default constructor available". There is a problem with the constexpr contructor when used in a variadic template. But anyway, since C++17, I would say that _v template variables are the preferred way, thus this modification follows C++17.
@@ -80,11 +80,11 @@ namespace iter { | |||
return ret; | |||
} | |||
|
|||
auto operator*() -> decltype(**sub_iter) { | |||
auto operator*() const -> decltype(**sub_iter) { |
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 places a greater requirement on the sub_iter to have a const 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.
If sub_iter is supposed to be an InputIterator, then it must have a const version of operator*. In C++17 standard:
[iterator.requirements.general]¶13 "In the following sections, a and b denote values of type X or const X"; then Table 95 "Input iterator requirements [...]" contains expression "* a".
Thus operator* must work on a const X.
If you think IteratorIterator should support also iterators that do not obey to the InputIterator requirements, both a const and non const version of the operators could be defined.
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 library has always supported things as long as they have some operator*, so I think to keep that the same the way would be to add a const overload instead of replacing the nonconst. Do that and I'll merge
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.
While trying to add a test case for non-const operator* (i.e. we should not add code unless there is a test that requires that code), I realized that IteratorIterator requires that TopIter is a RandomAccessIterator (requires the random_access_iterator_tag; there is a static_assert for that). Thus unless a class lies about being such an iterator, it must support const operator*. (Note that IteratorIterator also requires a const operator[], which I forgot in that version; I will correct that.)
Simple duplication of current operators *, -> and [], with const and non-const versions, would support an iterator having both the const and non-const versions (and also a standard iterator having only the const version). To do the tests requires to define a new special iterator, as vector::iterator does not have non-const versions.
To support non standard conforming iterators, without the const version, would require to remove the decltype return type of the operators, or use SFINAE, on the const version in IteratorIterator. Is this what you would like?
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.
ah you're right I forgot about that requirement. In that case I think we might be fine as is with just const versions
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.
Ok, so I added tests to verify that IteratorIterator operators are all working as specified by RandomAccessIterator in the standard, for both const and non-const iterators (having only const versions of *, -> and []). I passed each line of the requirements tables, I hope I did not miss anything (but I only test method results, I do not test the types).
I corrected the operator[] to be also const (as mentioned in my previous comment), to pass the RandomAccessIterator tests.
Those tests showed me that a weird operator- was not covered; in fact it was an incorrect operator where an expression like (2 - it) (subtracting an iterator from an integer) would give (it - 2). I thus simply removed that method.
@@ -51,8 +51,8 @@ namespace iter { | |||
using AsConst = decltype(std::as_const(std::declval<T&>())); | |||
|
|||
// iterator_type<C> is the type of C's iterator | |||
template <typename Container> | |||
using iterator_type = decltype(get_begin(std::declval<Container&>())); | |||
template <typename T> //TODO: See bug https://developercommunity.visualstudio.com/content/problem/252157/sfinae-error-depends-on-name-of-template-parameter.html for why we use T instead of Container. Should be changed back to Container when that bug is fixed in MSVC. |
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.
given that this is fixed in 16.0 I'm not sure how long this is worth keeping around
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 the same. But that modification was required to verify now that everything is working on msvc. I'm not sure when 16.0 will be released; current preview is 15.9 pre 2.
…ssIterator - Removed incorrect operaror - where (2 - it) would give (it - 2) - Added tests to cover all methods in iteratoriterator.hpp
Hi,
I know you were still not trying to support MSVC, because of a weird bug, but that bug only affected one line which was easy to modify (yes, I know it's weird to have to change the name of a parameter). So here is a version compiling without warning at /W4 (except one in catch.hpp which is not part of this project) with latest MSVC, and passing all tests in both release and debug builds.
I added CMake files so it's easy to build with different systems; I compiled with make/g++, ninja/msvc and Visual Studio as tests.
Note that I also corrected some bugs at the same time, as MSVC was stricter on some undefined behavior that was used (comparing iterators on different containers and decrementing begin).
I hope you will find this interesting and merge it in the official branch.