Skip to content

Commit fea9b08

Browse files
committed
Finish [sequence.reqmts]
1 parent e9d8635 commit fea9b08

File tree

2 files changed

+205
-9
lines changed

2 files changed

+205
-9
lines changed

include/beman/inplace_vector/inplace_vector.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1023,7 +1023,7 @@ struct inplace_vector : private __iv_detail::__storage::_t<__T, __N> {
10231023
requires(constructible_from<__T, ranges::range_reference_t<__R>> &&
10241024
movable<__T>)
10251025
{
1026-
assign(begin(__rg), end(__rg));
1026+
assign(std::begin(__rg), std::end(__rg));
10271027
}
10281028
constexpr void assign(size_type __n, const __T &__u)
10291029
requires(constructible_from<__T, const __T &> && movable<__T>)

tests/beman/inplace_vector/container_requirements.test.cpp

Lines changed: 204 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1+
#include "gtest/gtest.h"
2+
#include <algorithm>
3+
#include <array>
14
#include <gtest/gtest.h>
5+
#include <new>
26

37
#include "gtest_setup.hpp"
48

@@ -591,6 +595,8 @@ TYPED_TEST_SUITE(SequenceContainerRequirments, IVAllTypes);
591595
// Effects: Constructs a sequence container with n copies of t.
592596
// Postconditions: distance(u.begin(), u.end()) == n is true.
593597

598+
// See: Constructors/SizedValue
599+
594600
// X u(i, j);
595601
// Preconditions: T is Cpp17EmplaceConstructible into X from *i. For vector, if
596602
// the iterator does not meet the Cpp17ForwardIterator requirements
@@ -599,6 +605,8 @@ TYPED_TEST_SUITE(SequenceContainerRequirments, IVAllTypes);
599605
// the range [i, j) is dereferenced exactly once. Postconditions:
600606
// distance(u.begin(), u.end()) == distance(i, j) is true.
601607

608+
// See: Constructors/CopyIter
609+
602610
// X(from_range, rg)
603611
// Preconditions: T is Cpp17EmplaceConstructible into X from
604612
// *ranges​::​begin(rg). For vector, if R models neither
@@ -608,15 +616,56 @@ TYPED_TEST_SUITE(SequenceContainerRequirments, IVAllTypes);
608616
// Postconditions: distance(begin(), end()) == ranges​::​distance(rg) is
609617
// true.
610618

619+
// See: Constructors/CopyRanges
620+
611621
// X(il)
612622
// Effects: Equivalent to X(il.begin(), il.end()).
613623

624+
TYPED_TEST(SequenceContainerRequirments, ConstructorInitializerList) {
625+
using IV = TestFixture::IV;
626+
using T = TestFixture::T;
627+
628+
if (IV::capacity() == 0) {
629+
EXPECT_THROW(IV({T{20}}), beman::bad_alloc);
630+
return;
631+
}
632+
633+
IV device({T{20}});
634+
635+
IV correct;
636+
correct.emplace_back(20);
637+
EXPECT_EQ(device, correct);
638+
639+
if (IV::capacity() == 1)
640+
return;
641+
642+
device = IV({T{20}, T{21}});
643+
correct.emplace_back(21);
644+
645+
EXPECT_EQ(device, correct);
646+
}
647+
614648
// a = il
615649
// Result: X&.
616650
// Preconditions: T is Cpp17CopyInsertable into X and Cpp17CopyAssignable.
617651
// Effects: Assigns the range [il.begin(), il.end()) into a. All existing
618652
// elements of a are either assigned to or destroyed. Returns: *this.
619653

654+
TYPED_TEST(SequenceContainerRequirments, AssignInitializerList) {
655+
using IV = TestFixture::IV;
656+
using T = TestFixture::T;
657+
658+
if (IV::capacity() == 0) {
659+
IV device;
660+
EXPECT_THROW(device = {T{52}}, beman::bad_alloc);
661+
return;
662+
}
663+
664+
IV device;
665+
device = {T{20}};
666+
EXPECT_EQ(device, IV{T{20}});
667+
}
668+
620669
// a.emplace(p, args)
621670
// Result: iterator.
622671
// Preconditions: T is Cpp17EmplaceConstructible into X from args. For vector,
@@ -626,25 +675,33 @@ TYPED_TEST_SUITE(SequenceContainerRequirments, IVAllTypes);
626675
// indirectly refer to a value in a. — end note] Returns: An iterator that
627676
// points to the new element.
628677

678+
// See Modifiers/InsertEmplace
679+
629680
// a.insert(p, t)
630681
// Result: iterator.
631682
// Preconditions: T is Cpp17CopyInsertable into X. For vector, inplace_vector,
632683
// and deque, T is also Cpp17CopyAssignable. Effects: Inserts a copy of t before
633684
// p. Returns: An iterator that points to the copy of t inserted into a.
634685

686+
// See Modifiers/InsertSingleConstRef
687+
635688
// a.insert(p, rv)
636689
// Result: iterator.
637690
// Preconditions: T is Cpp17MoveInsertable into X. For vector, inplace_vector,
638691
// and deque, T is also Cpp17MoveAssignable. Effects: Inserts a copy of rv
639692
// before p. Returns: An iterator that points to the copy of rv inserted into a.
640693

694+
// See Modifiers/InsertSingleRV
695+
641696
// a.insert(p, n, t)
642697
// Result: iterator.
643698
// Preconditions: T is Cpp17CopyInsertable into X and Cpp17CopyAssignable.
644699
// Effects: Inserts n copies of t before p.
645700
// Returns: An iterator that points to the copy of the first element inserted
646701
// into a, or p if n == 0.
647702

703+
// See Modifiers/InsertMulti
704+
648705
// a.insert(p, i, j)
649706
// Result: iterator.
650707
// Preconditions: T is Cpp17EmplaceConstructible into X from *i. For vector,
@@ -655,6 +712,8 @@ TYPED_TEST_SUITE(SequenceContainerRequirments, IVAllTypes);
655712
// the range [i, j) shall be dereferenced exactly once. Returns: An iterator
656713
// that points to the copy of the first element inserted into a, or p if i == j.
657714

715+
// See Modifiere/InsertItrRange
716+
658717
// a.insert_range(p, rg)
659718
// Result: iterator.
660719
// Preconditions: T is Cpp17EmplaceConstructible into X from
@@ -666,6 +725,8 @@ TYPED_TEST_SUITE(SequenceContainerRequirments, IVAllTypes);
666725
// Returns: An iterator that points to the copy of the first element inserted
667726
// into a, or p if rg is empty.
668727

728+
// See Modifiers/InsertRange
729+
669730
// a.insert(p, il)
670731
// Effects: Equivalent to a.insert(p, il.begin(), il.end()).
671732
// a.erase(q)
@@ -675,28 +736,58 @@ TYPED_TEST_SUITE(SequenceContainerRequirments, IVAllTypes);
675736
// iterator that points to the element immediately following q prior to the
676737
// element being erased. If no such element exists, a.end() is returned.
677738

739+
// See Modifiers/InsertInitList
740+
678741
// a.erase(q1, q2)
679742
// Result: iterator.
680743
// Preconditions: For vector, inplace_vector, and deque, T is
681744
// Cpp17MoveAssignable. Effects: Erases the elements in the range [q1, q2).
682745
// Returns: An iterator that points to the element pointed to by q2 prior to any
683746
// elements being erased. If no such element exists, a.end() is returned.
684747

748+
// See Modifiers/EraseRange
749+
685750
// a.clear()
686751
// Result: void
687752
// Effects: Destroys all elements in a. Invalidates all references, pointers,
688753
// and iterators referring to the elements of a and may invalidate the
689754
// past-the-end iterator. Postconditions: a.empty() is true. Complexity: Linear.
690755

756+
TYPED_TEST(SequenceContainerRequirments, Clear) {
757+
using IV = TestFixture::IV;
758+
759+
auto device = this->unique();
760+
device.clear();
761+
EXPECT_EQ(device, IV{});
762+
}
763+
691764
// a.assign(i, j)
692765
// Result: void
693766
// Preconditions: T is Cpp17EmplaceConstructible into X from *i and assignable
694767
// from *i. For vector, if the iterator does not meet the forward iterator
695768
// requirements ([forward.iterators]), T is also Cpp17MoveInsertable into X.
696-
// Neither i nor j are iterators into a. Effects: Replaces elements in a with a
697-
// copy of [i, j). Invalidates all references, pointers and iterators referring
698-
// to the elements of a. For vector and deque, also invalidates the past-the-end
699-
// iterator. Each iterator in the range [i, j) is dereferenced exactly once.
769+
// Neither i nor j are iterators into a.
770+
// Effects: Replaces elements in a with a copy of [i, j). Invalidates all
771+
// references, pointers and iterators referring to the elements of a. For vector
772+
// and deque, also invalidates the past-the-end iterator. Each iterator in the
773+
// range [i, j) is dereferenced exactly once.
774+
775+
TYPED_TEST(SequenceContainerRequirments, AssignIterRange) {
776+
using IV = TestFixture::IV;
777+
using T = TestFixture::T;
778+
779+
auto device = this->unique();
780+
781+
const auto correct = this->unique();
782+
783+
device.assign(correct.begin(), correct.end());
784+
EXPECT_EQ(device, correct);
785+
786+
std::array<T, IV::capacity() + 1> ref;
787+
std::copy(correct.begin(), correct.end(), ref.begin());
788+
ref.back() = T{5};
789+
EXPECT_THROW(device.assign(ref.begin(), ref.end()), beman::bad_alloc);
790+
}
700791

701792
// a.assign_range(rg)
702793
// Result: void
@@ -710,13 +801,45 @@ TYPED_TEST_SUITE(SequenceContainerRequirments, IVAllTypes);
710801
// also invalidates the past-the-end iterator. Each iterator in the range rg is
711802
// dereferenced exactly once.
712803

804+
TYPED_TEST(SequenceContainerRequirments, AssignRange) {
805+
using IV = TestFixture::IV;
806+
using T = TestFixture::T;
807+
808+
auto device = this->unique();
809+
auto correct = this->unique();
810+
811+
device.assign_range(correct);
812+
EXPECT_EQ(device, correct);
813+
814+
std::array<T, IV::capacity() + 1> ref;
815+
std::copy(correct.begin(), correct.end(), ref.begin());
816+
ref.back() = T{5};
817+
EXPECT_THROW(device.assign_range(ref), beman::bad_alloc);
818+
}
819+
713820
// a.assign(il)
714821
// Effects: Equivalent to a.assign(il.begin(), il.end()).
715822

823+
TYPED_TEST(SequenceContainerRequirments, AssignFuncInitializerList) {
824+
using IV = TestFixture::IV;
825+
using T = TestFixture::T;
826+
827+
auto device = this->unique();
828+
829+
if (device.capacity() == 0) {
830+
EXPECT_THROW(device.assign({T{50}}), beman::bad_alloc);
831+
return;
832+
}
833+
834+
device.assign({T{50}});
835+
EXPECT_EQ(device, IV{T{50}});
836+
}
837+
716838
// a.assign(n, t)
717839
// Result: void
718840
// Preconditions: T is Cpp17CopyInsertable into X and Cpp17CopyAssignable. t is
719-
// not a reference into a. Effects: Replaces elements in a with n copies of t.
841+
// not a reference into a.
842+
// Effects: Replaces elements in a with n copies of t.
720843
// Invalidates all references, pointers and iterators referring to the elements
721844
// of a. For vector and deque, also invalidates the past-the-end iterator. For
722845
// every sequence container defined in this Clause and in [strings]:
@@ -753,42 +876,115 @@ TYPED_TEST_SUITE(SequenceContainerRequirments, IVAllTypes);
753876
// allocator is deduced for that parameter. The following operations are
754877
// provided for some types of sequence containers but not others. Operations
755878
// other than prepend_range and append_range are implemented so as to take
756-
// amortized constant time. Result: reference; const_reference for constant a.
879+
// amortized constant time.
880+
881+
TYPED_TEST(SequenceContainerRequirments, AssignMulti) {
882+
using IV = TestFixture::IV;
883+
using T = TestFixture::T;
884+
885+
auto device = this->unique();
886+
device.assign(0, T{6312});
887+
888+
EXPECT_EQ(device, IV());
889+
890+
if (device.capacity() > 0) {
891+
device.assign(1, T{6312});
892+
893+
EXPECT_EQ(device, IV{T{6312}});
894+
895+
device.assign(device.capacity(), T{5972});
896+
EXPECT_EQ(device, IV(IV::capacity(), T{5972}));
897+
}
898+
899+
device.clear();
900+
EXPECT_THROW(device.assign(device.capacity() + 1, T{12}), beman::bad_alloc);
901+
// TODO: Is this defined?
902+
// EXPECT_EQ(device, IV());
903+
}
904+
905+
// a.front()
906+
// Result: reference; const_reference for constant a.
757907
// Returns: *a.begin()
908+
909+
TYPED_TEST(SequenceContainerRequirments, Front) {
910+
auto device = this->unique();
911+
if (device.capacity() == 0)
912+
return;
913+
914+
EXPECT_EQ(device.front(), *device.begin());
915+
}
916+
758917
// a.back()
759918
// Result: reference; const_reference for constant a.
760919
// Effects: Equivalent to:
761920
// auto tmp = a.end();
762921
// --tmp;
763922
// return *tmp;
764-
// Remarks: Required for basic_string, array, deque, inplace_vector, list, and
765-
// vector.
923+
924+
TYPED_TEST(SequenceContainerRequirments, Back) {
925+
auto device = this->unique();
926+
if (device.capacity() == 0)
927+
return;
928+
929+
EXPECT_EQ(device.back(), *(device.end() - 1));
930+
}
766931

767932
// a.emplace_back(args)
768933
// Returns: a.back().
769934

935+
// See: Modifiers/EmplaceBack
936+
770937
// a.push_back(t)
771938
// Result: void
772939
// Preconditions: T is Cpp17CopyInsertable into X.
773940
// Effects: Appends a copy of t.
774941

942+
// See: Modifiers/EmplaceBack
943+
775944
// a.push_back(rv)
776945
// Result: void
777946
// Preconditions: T is Cpp17MoveInsertable into X.
778947
// Effects: Appends a copy of rv.
779948

949+
// See: Modifiers/PushBackRV
950+
780951
// a.pop_back()
781952
// Result: void
782953
// Preconditions: a.empty() is false.
783954
// Effects: Destroys the last element.
784955

956+
// See: Modifiers/PopBack
957+
785958
// a[n]
786959
// Result: reference; const_reference for constant
787960
// Effects: Equivalent to: return *(a.begin() + n);
788961

962+
TYPED_TEST(SequenceContainerRequirments, ElementAccess) {
963+
using IV = TestFixture::IV;
964+
using T = TestFixture::T;
965+
966+
auto device = this->unique();
967+
968+
for (auto i = 0ul; i < device.size(); ++i)
969+
EXPECT_EQ(device[i], *(device.begin() + i));
970+
}
971+
789972
// a.at(n)
790973
// Result: reference; const_reference for constant a
791974
// Returns: *(a.begin() + n)
792975
// Throws: out_of_range if n >= a.size().
793976

977+
TYPED_TEST(SequenceContainerRequirments, ElementAccessAt) {
978+
using IV = TestFixture::IV;
979+
using T = TestFixture::T;
980+
981+
auto device = this->unique();
982+
983+
for (auto i = 0ul; i < device.size(); ++i) {
984+
EXPECT_EQ(device.at(i), *(device.begin() + i));
985+
}
986+
987+
EXPECT_THROW(device.at(IV::capacity()), std::out_of_range);
988+
}
989+
794990
}; // namespace

0 commit comments

Comments
 (0)