• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>
MinSequenceContainerMinSequenceContainer27   explicit MinSequenceContainer(It first, It last) : data_(first, last) {}
MinSequenceContainerMinSequenceContainer28   MinSequenceContainer(std::initializer_list<T> il) : data_(il) {}
beginMinSequenceContainer29   iterator begin() { return iterator(data_.data()); }
beginMinSequenceContainer30   const_iterator begin() const { return const_iterator(data_.data()); }
cbeginMinSequenceContainer31   const_iterator cbegin() const { return const_iterator(data_.data()); }
endMinSequenceContainer32   iterator end() { return begin() + size(); }
endMinSequenceContainer33   const_iterator end() const { return begin() + size(); }
sizeMinSequenceContainer34   size_type size() const { return data_.size(); }
emptyMinSequenceContainer35   bool empty() const { return data_.empty(); }
36 
clearMinSequenceContainer37   void clear() { data_.clear(); }
38 
39   template <class It>
insertMinSequenceContainer40   iterator insert(const_iterator p, It first, It last) {
41     return from_vector_iterator(data_.insert(to_vector_iterator(p), first, last));
42   }
43 
insertMinSequenceContainer44   iterator insert(const_iterator p, T value) {
45     return from_vector_iterator(data_.insert(to_vector_iterator(p), std::move(value)));
46   }
47 
eraseMinSequenceContainer48   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 
eraseMinSequenceContainer52   iterator erase(const_iterator iter) { return from_vector_iterator(data_.erase(to_vector_iterator(iter))); }
53 
54   template <class... Args>
emplaceMinSequenceContainer55   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:
to_vector_iteratorMinSequenceContainer60   std::vector<T>::const_iterator to_vector_iterator(const_iterator cit) const { return cit - cbegin() + data_.begin(); }
61 
from_vector_iteratorMinSequenceContainer62   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>
requires(T & 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