128 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef SUPPORT_MIN_SEQUENCE_CONTAINER_H10#define SUPPORT_MIN_SEQUENCE_CONTAINER_H11 12#include <initializer_list>13#include <vector>14 15#include "test_iterators.h"16#include "test_macros.h"17 18template <class T,19 class Iterator = three_way_random_access_iterator<T*>,20 class ConstIterator = three_way_random_access_iterator<const T*>>21struct MinSequenceContainer {22 using value_type = T;23 using difference_type = int;24 using size_type = unsigned int;25 using iterator = Iterator;26 using const_iterator = ConstIterator;27 28 explicit MinSequenceContainer() = default;29 template <class It>30 explicit TEST_CONSTEXPR_CXX20 MinSequenceContainer(It first, It last) : data_(first, last) {}31 TEST_CONSTEXPR_CXX20 MinSequenceContainer(std::initializer_list<T> il) : data_(il) {}32#if TEST_STD_VER >= 2333 template <class Range>34 constexpr MinSequenceContainer(std::from_range_t, Range&& rg) : data_(std::from_range, std::forward<Range>(rg)) {}35#endif36 TEST_CONSTEXPR_CXX20 MinSequenceContainer(size_type n, T value) : data_(n, value) {}37 38 TEST_CONSTEXPR_CXX20 MinSequenceContainer& operator=(std::initializer_list<T> il) { data_ = il; }39 40 template <class It>41 TEST_CONSTEXPR_CXX20 void assign(It first, It last) {42 data_.assign(first, last);43 }44 TEST_CONSTEXPR_CXX20 void assign(std::initializer_list<T> il) { data_.assign(il); }45 TEST_CONSTEXPR_CXX20 void assign(size_type n, value_type t) { data_.assign(n, t); }46#if TEST_STD_VER >= 2347 template <class Range>48 constexpr void assign_range(Range&& rg) {49 data_.assign_range(std::forward<Range>(rg));50 }51#endif52 TEST_CONSTEXPR_CXX20 iterator begin() { return iterator(data_.data()); }53 TEST_CONSTEXPR_CXX20 const_iterator begin() const { return const_iterator(data_.data()); }54 TEST_CONSTEXPR_CXX20 const_iterator cbegin() const { return const_iterator(data_.data()); }55 TEST_CONSTEXPR_CXX20 iterator end() { return begin() + size(); }56 TEST_CONSTEXPR_CXX20 const_iterator end() const { return begin() + size(); }57 TEST_CONSTEXPR_CXX20 size_type size() const { return static_cast<size_type>(data_.size()); }58 TEST_CONSTEXPR_CXX20 bool empty() const { return data_.empty(); }59 60 TEST_CONSTEXPR_CXX20 void clear() { data_.clear(); }61 62 template <class It>63 TEST_CONSTEXPR_CXX20 iterator insert(const_iterator p, It first, It last) {64 return from_vector_iterator(data_.insert(to_vector_iterator(p), first, last));65 }66 67 TEST_CONSTEXPR_CXX20 iterator insert(const_iterator p, T value) {68 return from_vector_iterator(data_.insert(to_vector_iterator(p), std::move(value)));69 }70 71 TEST_CONSTEXPR_CXX20 iterator insert(const_iterator p, size_type n, T value) {72 return from_vector_iterator(data_.insert(to_vector_iterator(p), n, value));73 }74 75 TEST_CONSTEXPR_CXX20 iterator insert(const_iterator p, std::initializer_list<T> il) {76 return from_vector_iterator(data_.insert(to_vector_iterator(p), il));77 }78 79#if TEST_STD_VER >= 2380 template <class Range>81 constexpr iterator insert_range(const_iterator p, Range&& rg) {82 return from_vector_iterator(data_.insert_range(to_vector_iterator(p), std::forward<Range>(rg)));83 }84#endif85 86 TEST_CONSTEXPR_CXX20 iterator erase(const_iterator first, const_iterator last) {87 return from_vector_iterator(data_.erase(to_vector_iterator(first), to_vector_iterator(last)));88 }89 90 TEST_CONSTEXPR_CXX20 iterator erase(const_iterator iter) {91 return from_vector_iterator(data_.erase(to_vector_iterator(iter)));92 }93 94 template <class... Args>95 TEST_CONSTEXPR_CXX20 iterator emplace(const_iterator pos, Args&&... args) {96 return from_vector_iterator(data_.emplace(to_vector_iterator(pos), std::forward<Args>(args)...));97 }98 99private:100 TEST_CONSTEXPR_CXX20 std::vector<T>::const_iterator to_vector_iterator(const_iterator cit) const {101 return cit - cbegin() + data_.begin();102 }103 104 TEST_CONSTEXPR_CXX20 iterator from_vector_iterator(std::vector<T>::iterator it) {105 return it - data_.begin() + begin();106 }107 108 std::vector<T> data_;109};110 111namespace MinSequenceContainer_detail {112 113// MinSequenceContainer is non-allocator-aware, because flat_set supports114// such (non-STL) container types, and we want to make sure they are supported.115template <class T>116concept HasAllocatorType = requires { typename T::allocator_type; };117static_assert(!HasAllocatorType<MinSequenceContainer<int>>);118 119// MinSequenceContainer by itself doesn't support .emplace(), because we want120// to at least somewhat support (non-STL) container types with nothing but .insert().121template <class T>122concept HasEmplace = requires(T& t) { t.emplace(42); };123static_assert(!HasEmplace<MinSequenceContainer<int>>);124 125} // namespace MinSequenceContainer_detail126 127#endif // SUPPORT_MIN_SEQUENCE_CONTAINER_H128