@@ -30,16 +30,16 @@ One central design goal of SeqAn is to provide generic algorithms and data struc
3030types without reimplementing the same algorithms over and over again for particular types.
3131This has multiple benefits: improved maintainability due to an additional level of abstraction
3232and, more importantly, the ability to reuse the code with user provided types.
33- A familiar example for generic code is std::vector and the algorithms in the standard library.
34- They are * templates* which means that they can be * instantiated* with other types.
35- Most often the type cannot be arbitrary, because the template expects a particular interface from the type.
33+ A familiar example for generic code is ` std::vector ` and the algorithms in the standard library.
34+ They are * templates* , which means that they can be * instantiated* with other types.
35+ Most often the type cannot be arbitrary because the template expects a particular interface from the type.
3636
3737A SeqAn example is the local alignment algorithm.
3838It computes the best local match between two sequences over a finite alphabet.
3939The algorithm is generic in so far that it allows any alphabet that offers the minimal interface which
4040is used inside the algorithm (e.g. objects of the alphabet type must be equality comparable).
4141Before C++20, this could not be checked easily and using the interface with non-conforming types would result in
42- very hard to read compiler errors and consequently frustration of the user.
42+ very difficult to read compiler errors and consequently frustration of the user.
4343In the following part of the tutorial, you will learn how to * constrain* such template arguments of generic functions
4444and data structures and how this can have a huge impact on your code.
4545
@@ -93,12 +93,12 @@ If you plug in a type that does not model `Addable`, you will get a message stat
9393template backtrace.
9494
9595The standard library provides a set of [ predefined concepts] ( https://en.cppreference.com/w/cpp/concepts ) .
96- For our example above, the std::integral concept could have been used.
96+ For our example above, the ` std::integral ` concept could have been used.
9797
9898## Syntax variants
9999
100100Depending on the complexity of your constraint statements, three different syntaxes are available to enforce
101- constraints; all of the following are equivalent.
101+ constraints; the following are equivalent.
102102
103103(1) The "verbose syntax", especially useful when enforcing multiple constraints:
104104
@@ -128,8 +128,8 @@ auto add(std::integral auto const v1, std::integral auto const v2) // one const
128128}
129129```
130130
131- Different constraints can be applied to different template parameters and a single template parameter can be constrained
132- by multiple concepts.
131+ Different constraints can be applied to different template parameters, and a single template parameter can be
132+ constrained by multiple concepts.
133133Syntaxes can also be combined:
134134```cpp
135135template <std::integral t1, std::integral t2>
@@ -150,7 +150,7 @@ auto add(t1 const v1, t2 const v2)
150150Some people confuse concepts with * interfaces* .
151151Both can be used as an abstraction of concrete types, but interfaces have to be inherited from. → the abstraction
152152is explicit in the definition of the type.
153- Concepts on the other hand "describe properties from the outside". → types don't need to be related and don't need
153+ Concepts, on the other hand, "describe properties from the outside" → types don't need to be related and don't need
154154to "know about the concept" to model it.
155155
156156Furthermore, the polymorphism possible with concepts (see below) is faster, because it is resolved at compile-time while
@@ -195,79 +195,81 @@ int main()
195195```
196196
197197The ` print ` function (template) should print for every object ` v ` passed to it the result of ` to_char(v) ` and it should
198- be constrained to only accepts types that model seqan3::alphabet.
198+ be constrained to only accept types that model ` seqan3::alphabet ` .
199199Try calling ` print ` with a different type, e.g. ` int ` to make sure that it does.
200200\endassignment
201201\solution
202202\include doc/tutorial/03_concepts/overloading_solution1.cpp
203203\endsolution
204204
205205\assignment{Assignment 2: Static polymorphism with alphabets II}
206- Adapt your previous solution to handle nucleotides differently from the rest. For nucleotides, it should print both the value and its complement.
206+ Adapt your previous solution to handle nucleotides differently from the rest. For nucleotides, it should print both
207+ the value and its complement.
207208\endassignment
208209\solution
209210\include doc/tutorial/03_concepts/overloading_solution2.cpp
210211\endsolution
211212
212213## Partial template specialisation
213214
214- Similar to function template overloading it is possible to use concepts for partially specialising class and variable
215+ Similar to function template overloading, it is possible to use concepts for partially specialising class and variable
215216templates.
216217
217218\include doc/tutorial/03_concepts/specialisation.cpp
218219
219220This is a typical example of a "type transformation trait".
220- It maps one type to another type; in this case, it returns a type that is able to represent the square root of the
221+ It maps one type to another type; in this case, it returns a type that can represent the square root of the
221222"input type".
222223This can be used in generic algorithms to hold data in different types depending on the type of the input –
223224in this case, we could avoid half of the space consumption for unsigned integral types VS signed integral types.
224225
225- \note The std::same_as used above is a concept with two template parameters.
226+ \note The ` std::same_as ` used above is a concept with two template parameters.
226227It requires that both parameters are the same. The ` static_assert ` checks conditions at compile-time; it can be
227228used to verify whether a type or a combination of types model a concept. In the above case, we can use the combination
228229to check the "return type" of the transformation trait.
229230
230231# Concepts in SeqAn and this documentation
231232
232233SeqAn uses concepts extensively, for template specialisation/overloading, to avoid misuse and improve error messages.
233- Unfortunately, doxygen, the system used to generate this documentation, does not handle C++ concepts very well, yet.
234+ Unfortunately, doxygen, the system used to generate this documentation, does not handle C++ concepts very well yet.
234235That's why it's important to read the detailed documentation section of the constrained type, where we try to document
235236the requirements manually.
236- In some parts of the documentation concepts are called "interfaces", please don't let this confuse you.
237+ In some parts of the documentation, concepts are called "interfaces", please don't let this confuse you.
237238
238239<!-- To prevent misuse of templates and to clearly specify all public interfaces we use the concepts within
239240`static_assert`s in order to provoke more readable error messages. The thereby enforced requirements are also manually
240241documented with the respective instances. WE DO NOT ACTUALLY DO THIS... -->
241242
242243## Example: seqan3::bitpacked_sequence
243244
244- The class ` seqan3::bitpacked_sequence<alphabet_type> ` behaves just like ` std::vector<alphabet_type> ` but has an internal representation where multiple
245- values are packed into a single byte/word to save space. Also analog to ` std::vector ` , not every ` alphabet_type ` can
246- be used. To avoid misuse and weird error messages, the type is constrained.
245+ The class ` seqan3::bitpacked_sequence<alphabet_type> ` behaves just like ` std::vector<alphabet_type> ` but has an
246+ internal representation where multiple values are packed into a single byte/word to save space.
247+ Analogously to ` std::vector ` , not every ` alphabet_type ` can be used. To avoid misuse and weird error messages,
248+ the type is constrained.
247249
248250Have a look at the documentation of [ ` seqan3::bitpacked_sequence ` ] ( http://docs.seqan.de/seqan3/main_user/classseqan3_1_1bitpacked__sequence.html ) .
249251It has one constrained template parameter.
250252Do you understand the requirements imposed on ` alphabet_type ` when using the
251253[ ` seqan3::bitpacked_sequence ` ] ( http://docs.seqan.de/seqan3/main_user/classseqan3_1_1bitpacked__sequence.html ) ?
252254
253255\hint
254- In order to use the ` seqan3::bitpacked_sequence ` the ` alphabet_type ` must model the following:
256+ In order to use the ` seqan3::bitpacked_sequence ` , the ` alphabet_type ` must model the following:
255257
256- 1 . It needs to model [ ` std::regular ` ] ( https://en.cppreference.com/w/cpp/concepts/regular ) , a stl concept.
257- This only enforcing two other concepts: ` std::semiregular<T> && std::equality_comparable<T> ` .
258+ 1 . It needs to model [ ` std::regular ` ] ( https://en.cppreference.com/w/cpp/concepts/regular ) , an STL concept.
259+ This only enforces two other concepts: ` std::semiregular<T> && std::equality_comparable<T> ` .
258260 * ` std::semiregular<T> ` makes sure that your type is default initialisable (e.g. ` int i{}; ` ).
259261 * ` std::equality_comparable<T> ` makes sure you can compare your type with ` == ` (e.g. ` i == j ` ).
260262
261- It makes sense that in order to save a range of letters (of type ` alphabet_type ` ), you need them to be
263+ It makes sense that to save a range of letters (of type ` alphabet_type ` ), you need them to be
262264 default initialisable, for example s.t. you can easily resize your container.
263- Additionally, ` seqan3::bitpacked_sequence ` needs the ` alphabet_type ` to be comparable, in order be equality
265+ Additionally, ` seqan3::bitpacked_sequence ` needs the ` alphabet_type ` to be comparable, in order to be equality
264266 comparable itself (e.g. you can do ` bit_seq_1 == bit_seq_2 ` ).
265267
266268 2 . It needs to model [ ` seqan3::writable_semialphabet ` ] , a seqan3 concept.
267269 This again enforces two things:
268270 * ` seqan3::assign_rank_to ` needs to be defined for objects of this type.
269271 * the type shall model ` seqan3::semialphabet ` ,
270- which in summary enforces that your type is ordered (comparable via ` < ` ), shall be efficiently copyable and
272+ which in summary enforces that your type is ordered (comparable via ` < ` ), shall be efficiently copyable, and
271273 you should be able to call ` seqan3::alphabet_size(c) ` and ` seqan3::to_rank(c) ` (assuming ` c ` is of type ` alphabet_type ` ).
272274
273275\endhint
@@ -279,7 +281,7 @@ this concept is very SeqAn specific)?
279281
280282You can learn how to make your own alphabet model the SeqAn requirements in \ref howto_write_an_alphabet
281283
282- In order to understand what "make a type model a concept" means in practical terms, let's look at an easier
284+ To understand what "make a type model a concept" means in practical terms, let's look at an easier
283285example in the next section.
284286
285287# Satisfying a concept
@@ -294,8 +296,8 @@ Do you understand the requirements?
294296 1 . The type ` T ` needs to model ` has_foo<T> `
295297 Which again has two requirements:
296298 requirement 1: The type ` T ` has to have a * type member* called ` FOO `
297- requirement 2: The type ` T ` has to have a * member variable* calles ` foo `
298- 2 . ` std::same_as ` is a concept that checks whether two types are exaclty the same.
299+ requirement 2: The type ` T ` has to have a * member variable* called ` foo `
300+ 2 . ` std::same_as ` is a concept that checks whether two types are exactly the same.
299301 Thus, ` fooger ` requires, that the * type member* ` T::FOO ` is ` int ` .
300302\endhint
301303
0 commit comments