16 #include <type_traits>
22 namespace seqan3::detail
33 enum struct strong_type_skill
45 bitwise_lshift = 1 << 9,
46 bitwise_rshift = 1 << 10,
47 logical_and = 1 << 11,
49 logical_not = 1 << 13,
54 additive = add | subtract,
55 multiplicative = multiply | divide | modulo,
56 bitwise_logic = bitwise_and | bitwise_or | bitwise_xor | bitwise_not,
57 bitwise_shift = bitwise_lshift | bitwise_rshift,
58 logic = logical_and | logical_or | logical_not
68 constexpr
bool add_enum_bitwise_operators<seqan3::detail::strong_type_skill> =
true;
72 namespace seqan3::detail
76 template <
typename,
typename, strong_type_skill>
102 template <
typename strong_type_t>
103 SEQAN3_CONCEPT derived_from_strong_type = requires (strong_type_t && obj)
111 requires std::derived_from<std::remove_cvref_t<strong_type_t>,
112 strong_type<typename std::remove_reference_t<strong_type_t>::value_type,
172 template <
typename value_t,
typename derived_t, strong_type_skill skills_ = strong_type_skill::none>
177 static constexpr strong_type_skill skills = skills_;
179 using value_type = value_t;
185 constexpr strong_type() noexcept = default;
186 constexpr strong_type(strong_type const &) noexcept = default;
187 constexpr strong_type(strong_type &&) noexcept = default;
188 constexpr strong_type & operator= (strong_type const &) noexcept = default;
189 constexpr strong_type & operator= (strong_type &&) noexcept = default;
190 ~strong_type() noexcept = default;
193 constexpr explicit strong_type(value_t _value) : value(
std::
move(_value))
201 constexpr value_t &
get() & noexcept
207 constexpr value_t
const &
get() const & noexcept
213 constexpr value_t &&
get() && noexcept
219 constexpr value_t
const &&
get() const && noexcept
231 constexpr derived_t operator+(strong_type
const & other)
233 requires ((skills & strong_type_skill::add) != strong_type_skill::none)
236 return derived_t{
get() + other.get()};
240 constexpr derived_t operator-(strong_type
const & other)
242 requires ((skills & strong_type_skill::subtract) != strong_type_skill::none)
245 return derived_t{
get() - other.get()};
255 constexpr derived_t operator*(strong_type
const & other)
257 requires ((skills & strong_type_skill::multiply) != strong_type_skill::none)
260 return derived_t{
get() * other.get()};
264 constexpr derived_t operator/(strong_type
const & other)
266 requires ((skills & strong_type_skill::divide) != strong_type_skill::none)
269 return derived_t{
get() / other.get()};
273 constexpr derived_t operator%(strong_type
const & other)
275 requires ((skills & strong_type_skill::modulo) != strong_type_skill::none)
278 return derived_t{
get() % other.get()};
289 constexpr derived_t operator&(strong_type
const & other)
291 requires ((skills & strong_type_skill::bitwise_and) != strong_type_skill::none)
294 return derived_t{
get() & other.get()};
298 constexpr derived_t
operator|(strong_type
const & other)
300 requires ((skills & strong_type_skill::bitwise_or) != strong_type_skill::none)
303 return derived_t{
get() | other.get()};
307 constexpr derived_t operator^(strong_type
const & other)
309 requires ((skills & strong_type_skill::bitwise_xor) != strong_type_skill::none)
312 return derived_t{
get() ^ other.get()};
316 constexpr derived_t operator~()
318 requires ((skills & strong_type_skill::bitwise_not) != strong_type_skill::
none)
321 return derived_t{~
get()};
332 constexpr derived_t
operator<<(strong_type
const & other)
334 requires ((skills & strong_type_skill::bitwise_lshift) != strong_type_skill::none)
337 return derived_t{
get() << other.get()};
341 template <std::
integral
integral_t>
342 constexpr derived_t
operator<<(integral_t
const shift)
344 requires ((skills & strong_type_skill::bitwise_lshift) != strong_type_skill::none)
347 return derived_t{
get() << shift};
351 constexpr derived_t operator>>(strong_type
const & other)
353 requires ((skills & strong_type_skill::bitwise_rshift) != strong_type_skill::none)
356 return derived_t{
get() >> other.get()};
360 template <std::
integral
integral_t>
361 constexpr derived_t operator>>(integral_t
const shift)
363 requires ((skills & strong_type_skill::bitwise_rshift) != strong_type_skill::none)
366 return derived_t{
get() >> shift};
377 constexpr
bool operator&&(strong_type
const & other)
379 requires ((skills & strong_type_skill::logical_and) != strong_type_skill::none)
382 return get() && other.get();
386 constexpr
bool operator||(strong_type
const & other)
388 requires ((skills & strong_type_skill::logical_or) != strong_type_skill::none)
391 return get() || other.get();
395 constexpr
bool operator!()
397 requires ((skills & strong_type_skill::logical_not) != strong_type_skill::
none)
410 constexpr derived_t & operator++()
412 requires ((skills & strong_type_skill::increment) != strong_type_skill::
none)
416 return static_cast<derived_t &
>(*this);
420 constexpr derived_t operator++(
int)
422 requires ((skills & strong_type_skill::increment) != strong_type_skill::none)
425 derived_t tmp{
get()};
431 constexpr derived_t & operator--()
433 requires ((skills & strong_type_skill::decrement) != strong_type_skill::
none)
437 return static_cast<derived_t &
>(*this);
441 constexpr derived_t operator--(
int)
443 requires ((skills & strong_type_skill::decrement) != strong_type_skill::none)
446 derived_t tmp{
get()};
461 constexpr
bool operator==(strong_type
const & rhs)
const
463 requires ((skills & strong_type_skill::comparable) != strong_type_skill::none)
466 return get() == rhs.get();
470 constexpr
bool operator!=(strong_type
const & rhs)
const
472 requires ((skills & strong_type_skill::comparable) != strong_type_skill::none)
475 return !(*
this == rhs);
485 explicit constexpr
operator value_t() const
487 requires ((skills & strong_type_skill::convert) != strong_type_skill::
none)
521 template <
typename char_t, derived_from_strong_type strong_type_t>
522 debug_stream_type<char_t> &
operator<<(debug_stream_type<char_t> & stream, strong_type_t && value)
524 stream << value.get();
Provides seqan3::add_enum_bitwise_operators.
Provides seqan3::debug_stream and related types.
debug_stream_type< char_t > & operator<<(debug_stream_type< char_t > &stream, alignment_t &&alignment)
Stream operator for alignments, which are represented as tuples of aligned sequences.
Definition: debug_stream_alignment.hpp:101
auto operator|(validator1_type &&vali1, validator2_type &&vali2)
Enables the chaining of validators.
Definition: validators.hpp:1103
@ none
No flag is set.
Definition: debug_stream_type.hpp:32
constexpr auto convert
A view that converts each element in the input range (implicitly or via static_cast).
Definition: convert.hpp:74
auto const move
A view that turns lvalue-references into rvalue-references.
Definition: move.hpp:74
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
constexpr auto const & get(configuration< configs_t... > const &config) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: configuration.hpp:429
SeqAn specific customisations in the standard namespace.
Provides various type traits on generic types.