1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef SUPPORT_MIN_SEQUENCE_CONTAINER_H
10 #define SUPPORT_MIN_SEQUENCE_CONTAINER_H
12 #include <initializer_list>
15 #include "test_iterators.h"
17 template <class T
, class Iterator
= random_access_iterator
<T
*>, class ConstIterator
= random_access_iterator
<const T
*>>
18 struct MinSequenceContainer
{
20 using difference_type
= int;
21 using size_type
= unsigned int;
22 using iterator
= Iterator
;
23 using const_iterator
= ConstIterator
;
25 explicit MinSequenceContainer() = default;
27 explicit MinSequenceContainer(It first
, It last
) : data_(first
, last
) {}
28 MinSequenceContainer(std::initializer_list
<T
> il
) : data_(il
) {}
29 iterator
begin() { return iterator(data_
.data()); }
30 const_iterator
begin() const { return const_iterator(data_
.data()); }
31 const_iterator
cbegin() const { return const_iterator(data_
.data()); }
32 iterator
end() { return begin() + size(); }
33 const_iterator
end() const { return begin() + size(); }
34 size_type
size() const { return data_
.size(); }
35 bool empty() const { return data_
.empty(); }
37 void clear() { data_
.clear(); }
40 iterator
insert(const_iterator p
, It first
, It last
) {
41 return from_vector_iterator(data_
.insert(to_vector_iterator(p
), first
, last
));
44 iterator
insert(const_iterator p
, T value
) {
45 return from_vector_iterator(data_
.insert(to_vector_iterator(p
), std::move(value
)));
48 iterator
erase(const_iterator first
, const_iterator last
) {
49 return from_vector_iterator(data_
.erase(to_vector_iterator(first
), to_vector_iterator(last
)));
52 iterator
erase(const_iterator iter
) { return from_vector_iterator(data_
.erase(to_vector_iterator(iter
))); }
54 template <class... Args
>
55 iterator
emplace(const_iterator pos
, Args
&&... args
) {
56 return from_vector_iterator(data_
.emplace(to_vector_iterator(pos
), std::forward
<Args
>(args
)...));
60 std::vector
<T
>::const_iterator
to_vector_iterator(const_iterator cit
) const { return cit
- cbegin() + data_
.begin(); }
62 iterator
from_vector_iterator(std::vector
<T
>::iterator it
) { return it
- data_
.begin() + begin(); }
67 namespace MinSequenceContainer_detail
{
69 // MinSequenceContainer is non-allocator-aware, because flat_set supports
70 // such (non-STL) container types, and we want to make sure they are supported.
72 concept HasAllocatorType
= requires
{ typename
T::allocator_type
; };
73 static_assert(!HasAllocatorType
<MinSequenceContainer
<int>>);
75 // MinSequenceContainer by itself doesn't support .emplace(), because we want
76 // to at least somewhat support (non-STL) container types with nothing but .insert().
78 concept HasEmplace
= requires(T
& t
) { t
.emplace(42); };
79 static_assert(!HasEmplace
<MinSequenceContainer
<int>>);
81 } // namespace MinSequenceContainer_detail
83 #endif // SUPPORT_MIN_SEQUENCE_CONTAINER_H