SeqAn3  3.1.0-rc.1
The Modern C++ library for sequence analysis.
concept.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2021, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2021, 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 <seqan3/std/concepts>
16 #include <initializer_list>
17 #include <seqan3/std/iterator>
18 #include <type_traits>
19 
20 #include <seqan3/core/platform.hpp>
21 
22 #if SEQAN3_WORKAROUND_GCC_NO_CXX11_ABI || SEQAN3_WORKAROUND_GCC_83328
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 } // seqan3::detail
49 #endif // SEQAN3_WORKAROUND_GCC_NO_CXX11_ABI || SEQAN3_WORKAROUND_GCC_83328
50 
51 namespace seqan3
52 {
53 
72 template <typename type>
73 SEQAN3_CONCEPT container = requires (type val, type val2, type const cval, typename type::iterator it)
74 {
75  // member types
76  typename type::value_type;
77  typename type::reference;
78  typename type::const_reference;
79 /*
80  typename type::iterator;
81  requires std::forward_iterator<typename type::iterator>;
82  // NOTE check whether iterator is const convertible
83  SEQAN3_RETURN_TYPE_CONSTRAINT(it, std::same_as, typename type::const_iterator);
84 
85  typename type::const_iterator;
86  requires std::forward_iterator<typename type::const_iterator>;
87 
88  typename type::difference_type;
89  typename type::size_type;
90  requires std::is_same_v<
91  typename type::difference_type,
92  typename std::iterator_traits<typename type::iterator>::difference_type
93  >;
94  requires std::is_same_v<
95  typename std::iterator_traits<typename type::iterator>::difference_type,
96  typename std::iterator_traits<typename type::const_iterator>::difference_type
97  >;
98 */
99  // methods and operator
100  SEQAN3_RETURN_TYPE_CONSTRAINT(type{}, std::same_as, type); // default constructor
101  SEQAN3_RETURN_TYPE_CONSTRAINT(type{type{}}, std::same_as, type); // copy/move constructor
102  SEQAN3_RETURN_TYPE_CONSTRAINT(val = val2, std::same_as, type &); // assignment
103  { (&val)->~type() }; // destructor
104 
105  SEQAN3_RETURN_TYPE_CONSTRAINT(val.begin(), std::same_as, typename type::iterator);
106  SEQAN3_RETURN_TYPE_CONSTRAINT(val.end(), std::same_as, typename type::iterator);
107  SEQAN3_RETURN_TYPE_CONSTRAINT(cval.begin(), std::same_as, typename type::const_iterator);
108  SEQAN3_RETURN_TYPE_CONSTRAINT(cval.end(), std::same_as, typename type::const_iterator);
109  SEQAN3_RETURN_TYPE_CONSTRAINT(val.cbegin(), std::same_as, typename type::const_iterator);
110  SEQAN3_RETURN_TYPE_CONSTRAINT(val.cend(), std::same_as, typename type::const_iterator);
111 
112  requires !std::equality_comparable<typename type::value_type> || std::equality_comparable<type>;
113 
114  SEQAN3_RETURN_TYPE_CONSTRAINT(val.swap(val2), std::same_as, void);
115  SEQAN3_RETURN_TYPE_CONSTRAINT(swap(val, val2), std::same_as, void);
116  SEQAN3_RETURN_TYPE_CONSTRAINT(std::swap(val, val2), std::same_as, void);
117 
118  SEQAN3_RETURN_TYPE_CONSTRAINT(val.size(), std::same_as, typename type::size_type);
119  SEQAN3_RETURN_TYPE_CONSTRAINT(val.max_size(), std::same_as, typename type::size_type);
120  SEQAN3_RETURN_TYPE_CONSTRAINT(val.empty(), std::same_as, bool);
121 };
123 
140 template <typename type>
141 SEQAN3_CONCEPT sequence_container = requires (type val, type val2, type const cval)
142 {
143  requires container<type>;
144 
145  // construction
146  { type(typename type::size_type{}, typename type::value_type{}) };
147  { type{val2.begin(), val2.end()} }; // NOTE that this could be any input iterator:
148  { type{std::initializer_list<typename type::value_type>{}} };
149  SEQAN3_RETURN_TYPE_CONSTRAINT(val = std::initializer_list<typename type::value_type>{}, std::same_as, type &);
150 
151  // assignment NOTE return type is type & for std::string and void for other stl containers:
152  { val.assign(val2.begin(), val2.end()) };
153  { val.assign(std::initializer_list<typename type::value_type>{}) };
154  { val.assign(typename type::size_type{}, typename type::value_type{}) };
155 
156  // modify container
157  // TODO: how do you model this?
158  // SEQAN3_RETURN_TYPE_CONSTRAINT(val.emplace(typename type::const_iterator{}, ?),
159  // std::same_as, typename type::iterator);
160 #if SEQAN3_WORKAROUND_GCC_NO_CXX11_ABI
161  SEQAN3_RETURN_TYPE_CONSTRAINT(val.insert(val.begin(), val2.front()), std::same_as, typename type::iterator);
162  SEQAN3_RETURN_TYPE_CONSTRAINT(val.insert(val.begin(), typename type::value_type{}),
163  std::same_as, typename type::iterator);
164 
165  // std::string is missing the const_iterator versions for insert in pre-C++11 ABI
166  requires detail::is_basic_string_v<type> || requires(type val, type val2)
167 #else // ^^^ workaround / no workaround vvv
168  requires requires(type val, type val2)
169 #endif // SEQAN3_WORKAROUND_GCC_NO_CXX11_ABI
170  {
171  SEQAN3_RETURN_TYPE_CONSTRAINT(val.insert(val.cbegin(), val2.front()), std::same_as, typename type::iterator);
172  SEQAN3_RETURN_TYPE_CONSTRAINT(val.insert(val.cbegin(), typename type::value_type{}),
173  std::same_as, typename type::iterator);
174  SEQAN3_RETURN_TYPE_CONSTRAINT(val.insert(val.cbegin(), typename type::size_type{}, typename type::value_type{}),
175  std::same_as, typename type::iterator);
176  SEQAN3_RETURN_TYPE_CONSTRAINT(val.insert(val.cbegin(), val2.begin(), val2.end()),
177  std::same_as, typename type::iterator);
178 #if SEQAN3_WORKAROUND_GCC_83328
179  };
180 
181  requires detail::is_basic_string_v<type> || requires(type val)
182  {
183 // This function is not defined on strings (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83328).
184 #endif // SEQAN3_WORKAROUND_GCC_83328
185  SEQAN3_RETURN_TYPE_CONSTRAINT(val.insert(val.cbegin(), std::initializer_list<typename type::value_type>{}),
186  std::same_as, typename type::iterator);
187  };
188 
189 #if SEQAN3_WORKAROUND_GCC_NO_CXX11_ABI
190  // std::string is missing the const_iterator versions for erase in pre-C++11 ABI
191  requires detail::is_basic_string_v<type> || requires(type val)
192 #else // ^^^ workaround / no workaround vvv
193  requires requires(type val)
194 #endif // SEQAN3_WORKAROUND_GCC_NO_CXX11_ABI
195  {
196  SEQAN3_RETURN_TYPE_CONSTRAINT(val.erase(val.cbegin()), std::same_as, typename type::iterator);
197  SEQAN3_RETURN_TYPE_CONSTRAINT(val.erase(val.cbegin(), val.cend()), std::same_as, typename type::iterator);
198  };
199 
200  SEQAN3_RETURN_TYPE_CONSTRAINT(val.push_back(val.front()), std::same_as, void);
201  SEQAN3_RETURN_TYPE_CONSTRAINT(val.push_back(typename type::value_type{}), std::same_as, void);
202  SEQAN3_RETURN_TYPE_CONSTRAINT(val.pop_back(), std::same_as, void);
203  SEQAN3_RETURN_TYPE_CONSTRAINT(val.clear(), std::same_as, void);
204 
205  // access container
206  SEQAN3_RETURN_TYPE_CONSTRAINT(val.front(), std::same_as, typename type::reference);
207  SEQAN3_RETURN_TYPE_CONSTRAINT(cval.front(), std::same_as, typename type::const_reference);
208  SEQAN3_RETURN_TYPE_CONSTRAINT(val.back(), std::same_as, typename type::reference);
209  SEQAN3_RETURN_TYPE_CONSTRAINT(cval.back(), std::same_as, typename type::const_reference);
210 };
212 
229 template <typename type>
230 SEQAN3_CONCEPT random_access_container = requires (type val)
231 {
232  requires sequence_container<type>;
233 
234  // access container
235  SEQAN3_RETURN_TYPE_CONSTRAINT(val[0], std::same_as, typename type::reference);
236  SEQAN3_RETURN_TYPE_CONSTRAINT(val.at(0), std::same_as, typename type::reference);
237 
238  // modify container
239  SEQAN3_RETURN_TYPE_CONSTRAINT(val.resize(0), std::same_as, void);
240  SEQAN3_RETURN_TYPE_CONSTRAINT(val.resize(0, typename type::value_type{}), std::same_as, void);
241 };
243 
258 template <typename type>
259 SEQAN3_CONCEPT reservible_container = requires (type val)
260 {
262 
263  SEQAN3_RETURN_TYPE_CONSTRAINT(val.capacity(), std::same_as, typename type::size_type);
264  SEQAN3_RETURN_TYPE_CONSTRAINT(val.reserve(0), std::same_as, void);
265  SEQAN3_RETURN_TYPE_CONSTRAINT(val.shrink_to_fit(), std::same_as, void);
266 };
268 
269 } // namespace seqan3
The Concepts library.
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.
Provides C++20 additions to the <iterator> header.
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
SeqAn specific customisations in the standard namespace.
Definition: affine_cell_proxy.hpp:438
Provides platform and dependency checks.
#define SEQAN3_RETURN_TYPE_CONSTRAINT(expression, concept_name,...)
Same as writing {expression} -> concept_name<type1[, ...]> in a concept definition.
Definition: platform.hpp:57
Provides C++20 additions to the type_traits header.