CRTP base class to declare a strong typedef for a regular type to avoid ambiguous parameter settings in function calls. More...
#include <seqan3/core/detail/strong_type.hpp>
Public Types | |
using | value_type = value_t |
The underlying value type. | |
Public Member Functions | |
Constructor, destructor and assignment. | |
The standard functions are explicitly set to default. | |
constexpr | strong_type () noexcept=default |
Defaulted. | |
constexpr | strong_type (strong_type const &) noexcept=default |
Defaulted. | |
constexpr | strong_type (strong_type &&) noexcept=default |
Defaulted. | |
constexpr strong_type & | operator= (strong_type const &) noexcept=default |
Defaulted. | |
constexpr strong_type & | operator= (strong_type &&) noexcept=default |
Defaulted. | |
~strong_type () noexcept=default | |
Defaulted. | |
constexpr | strong_type (value_t _value) |
Construction from underlying value type. | |
Accessor. | |
constexpr value_t & | get () &noexcept |
Returns the underlying value. | |
constexpr value_t const & | get () const &noexcept |
Returns the underlying value. | |
constexpr value_t && | get () &&noexcept |
Returns the underlying value as rvalue. | |
constexpr value_t const && | get () const &&noexcept |
Returns the underlying value as rvalue. | |
Arithmetic additive operators. | |
Only available if the corresponding skills from seqan3::detail::strong_type_skill are added and the underlying type supports this operation. | |
constexpr derived_t | operator+ (strong_type const &other) |
Adds addition operator to the strong type. | |
constexpr derived_t | operator- (strong_type const &other) |
Adds subtraction operator to the strong type. | |
Arithmetic multiplicative operators. | |
Only available if the corresponding skills from seqan3::detail::strong_type_skill are added and the underlying type supports this operation. | |
constexpr derived_t | operator* (strong_type const &other) |
Adds multiplication operator to the strong type. | |
constexpr derived_t | operator/ (strong_type const &other) |
Adds division operator to the strong type. | |
constexpr derived_t | operator% (strong_type const &other) |
Adds modulo operator to the strong type. | |
Bitwise logic operators. | |
Only available if the corresponding skills from seqan3::detail::strong_type_skill are added and the underlying type supports this operation. | |
constexpr derived_t | operator& (strong_type const &other) |
Adds bitwise and operator to the strong type. | |
constexpr derived_t | operator| (strong_type const &other) |
Adds bitwise or operator to the strong type. | |
constexpr derived_t | operator^ (strong_type const &other) |
Adds bitwise xor operator to the strong type. | |
constexpr derived_t | operator~ () |
Adds bitwise not operator to the strong type. | |
Bitwise shift operators. | |
Only available if the corresponding skills from seqan3::detail::strong_type_skill are added and the underlying type supports this operation. | |
constexpr derived_t | operator<< (strong_type const &other) |
Adds bitwise left shift operator to the strong type. | |
template<std::integral integral_t> | |
constexpr derived_t | operator<< (integral_t const shift) |
Adds bitwise left shift operator to the strong type. | |
constexpr derived_t | operator>> (strong_type const &other) |
Adds bitwise right shift operator to the strong type. | |
template<std::integral integral_t> | |
constexpr derived_t | operator>> (integral_t const shift) |
Adds bitwise right shift operator to the strong type. | |
Logical operators. | |
Only available if the corresponding skills from seqan3::detail::strong_type_skill are added and the underlying type supports this operation. | |
constexpr bool | operator&& (strong_type const &other) |
Adds logical and operator to the strong type. | |
constexpr bool | operator|| (strong_type const &other) |
Adds logical or operator to the strong type. | |
constexpr bool | operator! () |
Adds logical not operator to the strong type. | |
Increment and decrement operators. | |
Only available if the corresponding skills from seqan3::detail::strong_type_skill are added and the underlying type supports this operation. | |
constexpr derived_t & | operator++ () |
Adds pre-increment operator to the strong type. | |
constexpr derived_t | operator++ (int) |
Adds post-increment operator to the strong type. | |
constexpr derived_t & | operator-- () |
Adds pre-decrement operator to the strong type. | |
constexpr derived_t | operator-- (int) |
Adds post-decrement operator to the strong type. | |
Comparison operators | |
Only available if the corresponding skill from seqan3::detail::strong_type_skill is added. Implemented as member functions because requires does not work on friends. | |
constexpr bool | operator== (strong_type const &rhs) const |
Return whether this instance is equal to rhs . | |
constexpr bool | operator!= (strong_type const &rhs) const |
Return whether this instance is not equal to rhs . | |
Conversion operators. | |
Only available if the corresponding skill from seqan3::detail::strong_type_skill is added. | |
constexpr | operator value_t () const |
Adds explicit conversion to it's underlying type. | |
Static Public Attributes | |
static constexpr strong_type_skill | skills = skills_ |
The selected skills for this type. | |
Private Attributes | |
value_t | value |
The underlying value, which is wrapped as a strong type. | |
Related Functions | |
(Note that these are not member functions.) | |
Formatted output | |
template<typename char_t , derived_from_strong_type strong_type_t> | |
debug_stream_type< char_t > & | operator<< (debug_stream_type< char_t > &stream, strong_type_t &&value) |
Formatted output to a seqan3::detail::debug_stream_type. More... | |
CRTP base class to declare a strong typedef for a regular type to avoid ambiguous parameter settings in function calls.
value_t | The underlying type to create a strong typedef for. |
derived_t | The derived class inheriting from this base class. see CRTP. |
skills_ | A set of skills to be added to the expressive type. |
There are many cases in which interfaces use ambiguous parameters which can be mixed up very easily. For example, if we consider an interface, that expects a window size and a number of maximal errors to search for possible hits in a region of interest, then both values might be given in form of an unsigned integer. The following snippet shows a typical interface:
The first parameter is the window size and the last parameter defines the error threshold. But, what happens if the user accidentally switches the window_size
with the error
parameter? In a bigger code base this mistake can be so subtle, that it becomes hard to figure out that the search interface was used in a wrong way. Also the compiler cannot detect this. In order to make this interface safe, we have to use a strong type. A strong type is expressive in what it actually represents as a value. In our toy example we could define two strong types as follows:
Our interface could now be changed to:
Now the user is forced to pass the parameters as their named type. If the parameter order is mixed up by accident the compiler would emit an error message, since the error
type is not convertible to the window_size
type and vice versa.
In most cases it is sufficient to protect the user interface from misuse by using strong types. Within the implementation the underlying value can then be extracted using the getter
-member functions of the seqan3::detail::strong_type class. However, there might be scenarios, where the strong type is exposed to the user to work with, but with a restricted set of operations that can be applied to the type. A familiar use case are the time typedefs of the std::chrono library. It is convenient for the user to subtract two time values representing, for example seconds, to get the duration between two time points. But not all operations like modulo or multiplication are really useful for this. In order to add skills to the seqan3::detail::strong_type the typedef can be further specialized with operations from the seqan3::detail::strong_type_skill enum. For example, we could further specify our error type to support increment and decrement operations.
|
related |
Formatted output to a seqan3::detail::debug_stream_type.
char_t | The char type of the seqan3::detail::debug_stream_type. |
strong_type_t | The strong type to print; must model seqan3::detail::derived_from_strong_type. |
[in,out] | stream | The output stream. |
[in] | value | The strong typed value to print. |
Prints the stored value of the given strong type.
stream_t &
A reference to the given stream.