This prevents the iterator overrides from being selected in
the case where non-iterator types are used as arguments, which
is of particular importance in cases where other overrides with
identical types exist.
Details
Diff Detail
- Build Status
Buildable 7124 Build 7124: arc lint + arc unit
Event Timeline
include/llvm/ADT/SmallVector.h | ||
---|---|---|
432–436 | This change doesn't do anything; typename and class are equivalent in this context. From your description, maybe you want something using std::enable_if? |
Enforce that template arguments are not integral types
The only possible conflicting override takes a size_type, and enforcing that the
type is not an integral type is much more straightforward than enforcing that it is
either an iterator, const iterator, pointer, or const pointer.
I think this is just about right - but the current SFINAE is only an exact match, so it wouldn't work for something that's, say, a RandomAccessIterator.
I believe you want to use std::is_convertible_to, rather than std::is_same (& maybe add coverage/a test case for a non-forward (for example, a random access - such as pointers to the begin/end of an array) for this).
I'm guessing using is_same should've broken some existing code in LLVM - I'm surprised it didn't break the unit test? So maybe I'm misunderstantding something about how this is working.
(I really appreciate your patience as we go around on this - sorry it's taken a few iterations)
The llvm test suite passes with this change, although I haven't verified clang's does yet. I'll add a test for a random access iterator, and update the enable_if if it doesn't work correctly.
assign(&arr[0], &arr[2]) fails both with is_same and is_convertible. Is that an acceptable usage of assign (and what you meant by random access iterator)? There's already a test case for assign(std::begin(arr), std::end(arr)), and that works fine with is_same.
It looks like random_access_iterator_tag inherits from input_iterator_tag (http://en.cppreference.com/w/cpp/iterator/iterator_tags), so maybe that's why is_same works?
Please add a test case using a non-forward iterator to demonstrate that the traits checking is working as intended.
I think something like this, maybe:
TYPED_TEST(SmallVectorTest, InsertRepeatedNonForwardIterator) { struct output_iterator { typedef std::output_iterator_tag iterator_category; typedef int value_type; typedef int difference_type; typedef value_type* pointer; typedef value_type& reference; // In theory other operations would be needed here, but they shouldn't be used in this test operator int() { return 2; } }; ... append(output_iterator(), output_iterator()) check that the vector describes the sequence {2, 2} }
I suppose in theory this should be tested for all 4 operations you're updating here - if there's a tidy way to do that, great, but otherwise I'd probably just test one of them.
Also there seem to be 3 test cases but 4 code changes. The ctor change isn't tested at all - could you test that?
This change doesn't do anything; typename and class are equivalent in this context. From your description, maybe you want something using std::enable_if?