1 //===----------------------------------------------------------------------===// 2 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef SUPPORT_MIN_SEQUENCE_CONTAINER_H 10 #define SUPPORT_MIN_SEQUENCE_CONTAINER_H 11 12 #include <initializer_list> 13 #include <vector> 14 15 #include "test_iterators.h" 16 17 template <class T, class Iterator = random_access_iterator<T*>, class ConstIterator = random_access_iterator<const T*>> 18 struct MinSequenceContainer { 19 using value_type = T; 20 using difference_type = int; 21 using size_type = unsigned int; 22 using iterator = Iterator; 23 using const_iterator = ConstIterator; 24 25 explicit MinSequenceContainer() = default; 26 template <class It> 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(); } 36 37 void clear() { data_.clear(); } 38 39 template <class It> 40 iterator insert(const_iterator p, It first, It last) { 41 return from_vector_iterator(data_.insert(to_vector_iterator(p), first, last)); 42 } 43 44 iterator insert(const_iterator p, T value) { 45 return from_vector_iterator(data_.insert(to_vector_iterator(p), std::move(value))); 46 } 47 48 iterator erase(const_iterator first, const_iterator last) { 49 return from_vector_iterator(data_.erase(to_vector_iterator(first), to_vector_iterator(last))); 50 } 51 52 iterator erase(const_iterator iter) { return from_vector_iterator(data_.erase(to_vector_iterator(iter))); } 53 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)...)); 57 } 58 59 private: 60 std::vector<T>::const_iterator to_vector_iterator(const_iterator cit) const { return cit - cbegin() + data_.begin(); } 61 62 iterator from_vector_iterator(std::vector<T>::iterator it) { return it - data_.begin() + begin(); } 63 64 std::vector<T> data_; 65 }; 66 67 namespace MinSequenceContainer_detail { 68 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. 71 template <class T> 72 concept HasAllocatorType = requires { typename T::allocator_type; }; 73 static_assert(!HasAllocatorType<MinSequenceContainer<int>>); 74 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(). 77 template <class T> 78 concept HasEmplace = requires(T& t) { t.emplace(42); }; 79 static_assert(!HasEmplace<MinSequenceContainer<int>>); 80 81 } // namespace MinSequenceContainer_detail 82 83 #endif // SUPPORT_MIN_SEQUENCE_CONTAINER_H 84