SeqAn3 3.4.0-rc.3
The Modern C++ library for sequence analysis.
Loading...
Searching...
No Matches
utility/container/concept.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2006-2024 Knut Reinert & Freie Universität Berlin
2// SPDX-FileCopyrightText: 2016-2024 Knut Reinert & MPI für molekulare Genetik
3// SPDX-License-Identifier: BSD-3-Clause
4
10#pragma once
11
12#include <concepts>
13#include <initializer_list>
14#include <iterator>
15#include <type_traits>
16
18
19#if SEQAN3_WORKAROUND_GCC_NO_CXX11_ABI
20# include <string>
21
22namespace seqan3::detail
23{
24
28template <typename basic_string_t>
29struct is_basic_string : std::false_type
30{};
31
35template <typename value_t, typename traits_t, typename allocator_t>
36struct is_basic_string<std::basic_string<value_t, traits_t, allocator_t>> : std::true_type
37{};
38
42template <typename basic_string_t>
43constexpr bool is_basic_string_v = is_basic_string<basic_string_t>::value;
44
45} // namespace seqan3::detail
46#endif // SEQAN3_WORKAROUND_GCC_NO_CXX11_ABI
47
48namespace seqan3
49{
50
69template <typename type>
70concept container = requires (type val, type val2, type const cval, typename type::iterator it) {
71 // member types
72 typename type::value_type;
73 typename type::reference;
74 typename type::const_reference;
75 /*
76 typename type::iterator;
77 requires std::forward_iterator<typename type::iterator>;
78 // NOTE check whether iterator is const convertible
79 {it} -> std::same_as<typename type::const_iterator>;
80
81 typename type::const_iterator;
82 requires std::forward_iterator<typename type::const_iterator>;
83
84 typename type::difference_type;
85 typename type::size_type;
86 requires std::is_same_v<
87 typename type::difference_type,
88 typename std::iterator_traits<typename type::iterator>::difference_type
89 >;
90 requires std::is_same_v<
91 typename std::iterator_traits<typename type::iterator>::difference_type,
92 typename std::iterator_traits<typename type::const_iterator>::difference_type
93 >;
94*/
95 // methods and operator
96 { type{} } -> std::same_as<type>; // default constructor
97 { type{type{}} } -> std::same_as<type>; // copy/move constructor
98 { val = val2 } -> std::same_as<type &>; // assignment
99 { (&val)->~type() }; // destructor
100
101 { val.begin() } -> std::same_as<typename type::iterator>;
102 { val.end() } -> std::same_as<typename type::iterator>;
103 { cval.begin() } -> std::same_as<typename type::const_iterator>;
104 { cval.end() } -> std::same_as<typename type::const_iterator>;
105 { val.cbegin() } -> std::same_as<typename type::const_iterator>;
106 { val.cend() } -> std::same_as<typename type::const_iterator>;
107
108 requires !std::equality_comparable<typename type::value_type> || std::equality_comparable<type>;
109
110 { val.swap(val2) } -> std::same_as<void>;
111 { swap(val, val2) } -> std::same_as<void>;
112 { std::swap(val, val2) } -> std::same_as<void>;
113
114 { val.size() } -> std::same_as<typename type::size_type>;
115 { val.max_size() } -> std::same_as<typename type::size_type>;
116 { val.empty() } -> std::same_as<bool>;
117};
119
136template <typename type>
137concept sequence_container = requires (type val, type val2, type const cval) {
138 requires container<type>;
139
140 // construction
141 { type(typename type::size_type{}, typename type::value_type{}) };
142 { type{val2.begin(), val2.end()} }; // NOTE that this could be any input iterator:
144 { val = std::initializer_list<typename type::value_type>{} } -> std::same_as<type &>;
145
146 // assignment NOTE return type is type & for std::string and void for other stl containers:
147 { val.assign(val2.begin(), val2.end()) };
149 { val.assign(typename type::size_type{}, typename type::value_type{}) };
150
151 // modify container
152 // TODO: how do you model this?
153 // {val.emplace(typename type::const_iterator{}, ?)} -> std::same_as<typename type::iterator>;
154#if SEQAN3_WORKAROUND_GCC_NO_CXX11_ABI
155 { val.insert(val.begin(), val2.front()) } -> std::same_as<typename type::iterator>;
156 { val.insert(val.begin(), typename type::value_type{}) } -> std::same_as<typename type::iterator>;
157
158 // std::string is missing the const_iterator versions for insert in pre-C++11 ABI
159 requires detail::is_basic_string_v<type>
160 || requires (type val, type val2)
161#else // ^^^ workaround / no workaround vvv
162 requires requires (type val, type val2)
163#endif // SEQAN3_WORKAROUND_GCC_NO_CXX11_ABI
164 {
165 { val.insert(val.cbegin(), val2.front()) } -> std::same_as<typename type::iterator>;
166 { val.insert(val.cbegin(), typename type::value_type{}) } -> std::same_as<typename type::iterator>;
167 {
168 val.insert(val.cbegin(), typename type::size_type{}, typename type::value_type{})
169 } -> std::same_as<typename type::iterator>;
170 { val.insert(val.cbegin(), val2.begin(), val2.end()) } -> std::same_as<typename type::iterator>;
171 {
172 val.insert(val.cbegin(), std::initializer_list<typename type::value_type>{})
173 } -> std::same_as<typename type::iterator>;
174 };
175
176#if SEQAN3_WORKAROUND_GCC_NO_CXX11_ABI
177 // std::string is missing the const_iterator versions for erase in pre-C++11 ABI
178 requires detail::is_basic_string_v<type>
179 || requires (type val)
180#else // ^^^ workaround / no workaround vvv
181 requires requires (type val)
182#endif // SEQAN3_WORKAROUND_GCC_NO_CXX11_ABI
183 {
184 { val.erase(val.cbegin()) } -> std::same_as<typename type::iterator>;
185 { val.erase(val.cbegin(), val.cend()) } -> std::same_as<typename type::iterator>;
186 };
187
188 { val.push_back(val.front()) } -> std::same_as<void>;
189 { val.push_back(typename type::value_type{}) } -> std::same_as<void>;
190 { val.pop_back() } -> std::same_as<void>;
191 { val.clear() } -> std::same_as<void>;
192
193 // access container
194 { val.front() } -> std::same_as<typename type::reference>;
195 { cval.front() } -> std::same_as<typename type::const_reference>;
196 { val.back() } -> std::same_as<typename type::reference>;
197 { cval.back() } -> std::same_as<typename type::const_reference>;
198};
200
217template <typename type>
218concept random_access_container = requires (type val) {
220
221 // access container
222 { val[0] } -> std::same_as<typename type::reference>;
223 { val.at(0) } -> std::same_as<typename type::reference>;
224
225 // modify container
226 { val.resize(0) } -> std::same_as<void>;
227 { val.resize(0, typename type::value_type{}) } -> std::same_as<void>;
228};
230
245template <typename type>
246concept reservible_container = requires (type val) {
248
249 { val.capacity() } -> std::same_as<typename type::size_type>;
250 { val.reserve(0) } -> std::same_as<void>;
251 { val.shrink_to_fit() } -> std::same_as<void>;
252};
254
255} // namespace seqan3
The (most general) container concept as defined by the standard library.
A more refined container concept than seqan3::sequence_container.
A more refined container concept than seqan3::random_access_container.
A more refined container concept than seqan3::container.
The main SeqAn3 namespace.
Definition aligned_sequence_concept.hpp:26
SeqAn specific customisations in the standard namespace.
Provides platform and dependency checks.
T swap(T... args)
Hide me