SeqAn3  3.2.0-rc.1
The Modern C++ library for sequence analysis.
utility/container/concept.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2022, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2022, Knut Reinert & MPI für molekulare Genetik
4 // This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
5 // shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md
6 // -----------------------------------------------------------------------------------------------------
7 
13 #pragma once
14 
15 #include <concepts>
16 #include <initializer_list>
17 #include <iterator>
18 #include <type_traits>
19 
20 #include <seqan3/core/platform.hpp>
21 
22 #if SEQAN3_WORKAROUND_GCC_NO_CXX11_ABI
23 # include <string>
24 
25 namespace seqan3::detail
26 {
27 
31 template <typename basic_string_t>
32 struct is_basic_string : std::false_type
33 {};
34 
38 template <typename value_t, typename traits_t, typename allocator_t>
39 struct is_basic_string<std::basic_string<value_t, traits_t, allocator_t>> : std::true_type
40 {};
41 
45 template <typename basic_string_t>
46 constexpr bool is_basic_string_v = is_basic_string<basic_string_t>::value;
47 
48 } // namespace seqan3::detail
49 #endif // SEQAN3_WORKAROUND_GCC_NO_CXX11_ABI
50 
51 namespace seqan3
52 {
53 
72 template <typename type>
73 concept container = requires (type val, type val2, type const cval, typename type::iterator it) {
74  // member types
75  typename type::value_type;
76  typename type::reference;
77  typename type::const_reference;
78  /*
79  typename type::iterator;
80  requires std::forward_iterator<typename type::iterator>;
81  // NOTE check whether iterator is const convertible
82  {it} -> std::same_as<typename type::const_iterator>;
83 
84  typename type::const_iterator;
85  requires std::forward_iterator<typename type::const_iterator>;
86 
87  typename type::difference_type;
88  typename type::size_type;
89  requires std::is_same_v<
90  typename type::difference_type,
91  typename std::iterator_traits<typename type::iterator>::difference_type
92  >;
93  requires std::is_same_v<
94  typename std::iterator_traits<typename type::iterator>::difference_type,
95  typename std::iterator_traits<typename type::const_iterator>::difference_type
96  >;
97 */
98  // methods and operator
99  {
100  type{}
101  } -> std::same_as<type>; // default constructor
102  {
103  type{type{}}
104  } -> std::same_as<type>; // copy/move constructor
105  {
106  val = val2
107  } -> std::same_as<type &>; // assignment
108  {
109  (&val)->~type()
110  }; // destructor
111 
112  {
113  val.begin()
114  } -> std::same_as<typename type::iterator>;
115  {
116  val.end()
117  } -> std::same_as<typename type::iterator>;
118  {
119  cval.begin()
120  } -> std::same_as<typename type::const_iterator>;
121  {
122  cval.end()
123  } -> std::same_as<typename type::const_iterator>;
124  {
125  val.cbegin()
126  } -> std::same_as<typename type::const_iterator>;
127  {
128  val.cend()
129  } -> std::same_as<typename type::const_iterator>;
130 
131  requires !std::equality_comparable<typename type::value_type> || std::equality_comparable<type>;
132 
133  {
134  val.swap(val2)
135  } -> std::same_as<void>;
136  {
137  swap(val, val2)
138  } -> std::same_as<void>;
139  {
140  std::swap(val, val2)
141  } -> std::same_as<void>;
142 
143  {
144  val.size()
145  } -> std::same_as<typename type::size_type>;
146  {
147  val.max_size()
148  } -> std::same_as<typename type::size_type>;
149  {
150  val.empty()
151  } -> std::same_as<bool>;
152  };
154 
171 template <typename type>
172 concept sequence_container =
173  requires (type val, type val2, type const cval) {
175 
176  // construction
177  {
178  type(typename type::size_type{}, typename type::value_type{})
179  };
180  {
181  type{val2.begin(), val2.end()}
182  }; // NOTE that this could be any input iterator:
183  {
185  };
186  {
188  } -> std::same_as<type &>;
189 
190  // assignment NOTE return type is type & for std::string and void for other stl containers:
191  {
192  val.assign(val2.begin(), val2.end())
193  };
194  {
196  };
197  {
198  val.assign(typename type::size_type{}, typename type::value_type{})
199  };
200 
201  // modify container
202  // TODO: how do you model this?
203  // {val.emplace(typename type::const_iterator{}, ?)} -> std::same_as<typename type::iterator>;
204 #if SEQAN3_WORKAROUND_GCC_NO_CXX11_ABI
205  {
206  val.insert(val.begin(), val2.front())
207  } -> std::same_as<typename type::iterator>;
208  {
209  val.insert(val.begin(), typename type::value_type{})
210  } -> std::same_as<typename type::iterator>;
211 
212  // std::string is missing the const_iterator versions for insert in pre-C++11 ABI
213  requires detail::is_basic_string_v<type>
214  || requires (type val, type val2)
215 #else // ^^^ workaround / no workaround vvv
216  requires requires (type val, type val2)
217 #endif // SEQAN3_WORKAROUND_GCC_NO_CXX11_ABI
218  {
219  {
220  val.insert(val.cbegin(), val2.front())
221  } -> std::same_as<typename type::iterator>;
222  {
223  val.insert(val.cbegin(), typename type::value_type{})
224  } -> std::same_as<typename type::iterator>;
225  {
226  val.insert(val.cbegin(), typename type::size_type{}, typename type::value_type{})
227  } -> std::same_as<typename type::iterator>;
228  {
229  val.insert(val.cbegin(), val2.begin(), val2.end())
230  } -> std::same_as<typename type::iterator>;
231  {
232  val.insert(val.cbegin(), std::initializer_list<typename type::value_type>{})
233  } -> std::same_as<typename type::iterator>;
234  };
235 
236 #if SEQAN3_WORKAROUND_GCC_NO_CXX11_ABI
237  // std::string is missing the const_iterator versions for erase in pre-C++11 ABI
238  requires detail::is_basic_string_v<type>
239  || requires (type val)
240 #else // ^^^ workaround / no workaround vvv
241  requires requires (type val)
242 #endif // SEQAN3_WORKAROUND_GCC_NO_CXX11_ABI
243  {
244  {
245  val.erase(val.cbegin())
246  } -> std::same_as<typename type::iterator>;
247  {
248  val.erase(val.cbegin(), val.cend())
249  } -> std::same_as<typename type::iterator>;
250  };
251 
252  {
253  val.push_back(val.front())
254  } -> std::same_as<void>;
255  {
256  val.push_back(typename type::value_type{})
257  } -> std::same_as<void>;
258  {
259  val.pop_back()
260  } -> std::same_as<void>;
261  {
262  val.clear()
263  } -> std::same_as<void>;
264 
265  // access container
266  {
267  val.front()
268  } -> std::same_as<typename type::reference>;
269  {
270  cval.front()
271  } -> std::same_as<typename type::const_reference>;
272  {
273  val.back()
274  } -> std::same_as<typename type::reference>;
275  {
276  cval.back()
277  } -> std::same_as<typename type::const_reference>;
278  };
280 
297 template <typename type>
298 concept random_access_container = requires (type val) {
300 
301  // access container
302  {
303  val[0]
304  } -> std::same_as<typename type::reference>;
305  {
306  val.at(0)
307  } -> std::same_as<typename type::reference>;
308 
309  // modify container
310  {
311  val.resize(0)
312  } -> std::same_as<void>;
313  {
314  val.resize(0, typename type::value_type{})
315  } -> std::same_as<void>;
316  };
318 
333 template <typename type>
334 concept reservible_container = requires (type val) {
336 
337  {
338  val.capacity()
339  } -> std::same_as<typename type::size_type>;
340  {
341  val.reserve(0)
342  } -> std::same_as<void>;
343  {
344  val.shrink_to_fit()
345  } -> std::same_as<void>;
346  };
348 
349 } // namespace seqan3
The <concepts> header from C++20's standard library.
requires requires
The rank_type of the semi-alphabet; defined as the return type of seqan3::to_rank....
Definition: alphabet/concept.hpp:164
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:29
SeqAn specific customisations in the standard namespace.
Provides platform and dependency checks.
T swap(T... args)