@@ -398,6 +398,8 @@ struct some_struct {
398398 std::string swap_val;
399399};
400400
401+ struct derives_from_some_struct : some_struct {};
402+
401403std::vector<int >::const_iterator begin (const some_struct &s) {
402404 return s.data .begin ();
403405}
@@ -500,6 +502,15 @@ TEST(STLExtrasTest, ToVector) {
500502 }
501503}
502504
505+ TEST (STLExtrasTest, AllTypesEqual) {
506+ static_assert (all_types_equal_v<>);
507+ static_assert (all_types_equal_v<int >);
508+ static_assert (all_types_equal_v<int , int , int >);
509+
510+ static_assert (!all_types_equal_v<int , int , unsigned int >);
511+ static_assert (!all_types_equal_v<int , int , float >);
512+ }
513+
503514TEST (STLExtrasTest, ConcatRange) {
504515 std::vector<int > Expected = {1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 };
505516 std::vector<int > Test;
@@ -532,6 +543,43 @@ TEST(STLExtrasTest, ConcatRangeADL) {
532543 EXPECT_THAT (concat<const int >(S0, S1), ElementsAre (1 , 2 , 3 , 4 ));
533544}
534545
546+ TEST (STLExtrasTest, ConcatRangePtrToSameClass) {
547+ some_namespace::some_struct S0{};
548+ some_namespace::some_struct S1{};
549+ SmallVector<some_namespace::some_struct *> V0{&S0};
550+ SmallVector<some_namespace::some_struct *> V1{&S1, &S1};
551+
552+ // Dereferencing all iterators yields `some_namespace::some_struct *&`; no
553+ // conversion takes place, `reference_type` is
554+ // `some_namespace::some_struct *&`.
555+ auto C = concat<some_namespace::some_struct *>(V0, V1);
556+ static_assert (
557+ std::is_same_v<decltype (*C.begin ()), some_namespace::some_struct *&>);
558+ EXPECT_THAT (C, ElementsAre (&S0, &S1, &S1));
559+ // `reference_type` should still allow container modification.
560+ for (auto &i : C)
561+ if (i == &S0)
562+ i = nullptr ;
563+ EXPECT_THAT (C, ElementsAre (nullptr , &S1, &S1));
564+ }
565+
566+ TEST (STLExtrasTest, ConcatRangePtrToDerivedClass) {
567+ some_namespace::some_struct S0{};
568+ some_namespace::derives_from_some_struct S1{};
569+ SmallVector<some_namespace::some_struct *> V0{&S0};
570+ SmallVector<some_namespace::derives_from_some_struct *> V1{&S1, &S1};
571+
572+ // Dereferencing all iterators yields different (but convertible types);
573+ // conversion takes place, `reference_type` is
574+ // `some_namespace::some_struct *`.
575+ auto C = concat<some_namespace::some_struct *>(V0, V1);
576+ static_assert (
577+ std::is_same_v<decltype (*C.begin ()), some_namespace::some_struct *>);
578+ EXPECT_THAT (C,
579+ ElementsAre (&S0, static_cast <some_namespace::some_struct *>(&S1),
580+ static_cast <some_namespace::some_struct *>(&S1)));
581+ }
582+
535583TEST (STLExtrasTest, MakeFirstSecondRangeADL) {
536584 // Make sure that we use the `begin`/`end` functions from `some_namespace`,
537585 // using ADL.
0 commit comments