SeqAn3 3.1.0
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
21
22#if SEQAN3_WORKAROUND_GCC_NO_CXX11_ABI || SEQAN3_WORKAROUND_GCC_83328
23#include <string>
24
25namespace seqan3::detail
26{
27
31template <typename basic_string_t>
32struct is_basic_string : std::false_type
33{};
34
38template <typename value_t, typename traits_t, typename allocator_t>
39struct is_basic_string<std::basic_string<value_t, traits_t, allocator_t>> : std::true_type
40{};
41
45template <typename basic_string_t>
46constexpr 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
51namespace seqan3
52{
53
72template <typename type>
73SEQAN3_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
140template <typename type>
141SEQAN3_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:
150
151 // assignment NOTE return type is type & for std::string and void for other stl containers:
152 { val.assign(val2.begin(), val2.end()) };
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
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
229template <typename type>
230SEQAN3_CONCEPT random_access_container = requires (type val)
231{
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
258template <typename type>
259SEQAN3_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> header from C++20's standard 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.
The <iterator> header from C++20's standard library.
The main SeqAn3 namespace.
Definition: cigar_operation_table.hpp:2
SeqAn specific customisations in the standard namespace.
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
T swap(T... args)