15 #include <type_traits>
21 namespace seqan3::detail
27 enum struct strong_type_skill
39 bitwise_lshift = 1 << 9,
40 bitwise_rshift = 1 << 10,
41 logical_and = 1 << 11,
43 logical_not = 1 << 13,
47 additive = add | subtract,
48 multiplicative = multiply | divide | modulo,
49 bitwise_logic = bitwise_and | bitwise_or | bitwise_xor | bitwise_not,
50 bitwise_shift = bitwise_lshift | bitwise_rshift,
51 logic = logical_and | logical_or | logical_not
59 constexpr
bool add_enum_bitwise_operators<seqan3::detail::strong_type_skill> =
true;
63 namespace seqan3::detail
114 template <
typename value_t,
typename derived_t, strong_type_skill skills = strong_type_skill::none>
120 using value_type = value_t;
126 constexpr strong_type() noexcept = default;
127 constexpr strong_type(strong_type const &) noexcept = default;
128 constexpr strong_type(strong_type &&) noexcept = default;
129 constexpr strong_type & operator= (strong_type const &) noexcept = default;
130 constexpr strong_type & operator= (strong_type &&) noexcept = default;
131 ~strong_type() noexcept = default;
134 constexpr explicit strong_type(value_t _value) : value(
std::
move(_value))
141 constexpr value_t &
get() & noexcept
148 constexpr value_t
const &
get() const & noexcept
154 constexpr value_t &&
get() && noexcept
160 constexpr value_t
const &&
get() const && noexcept
171 constexpr derived_t operator+(strong_type
const & other)
174 requires ((skills & strong_type_skill::add) != strong_type_skill::none)
177 return derived_t{
get() + other.get()};
181 constexpr derived_t operator-(strong_type
const & other)
183 requires ((skills & strong_type_skill::subtract) != strong_type_skill::none)
186 return derived_t{
get() - other.get()};
195 constexpr derived_t operator*(strong_type
const & other)
198 requires ((skills & strong_type_skill::multiply) != strong_type_skill::none)
201 return derived_t{
get() * other.get()};
205 constexpr derived_t operator/(strong_type
const & other)
207 requires ((skills & strong_type_skill::divide) != strong_type_skill::none)
210 return derived_t{
get() / other.get()};
214 constexpr derived_t operator%(strong_type
const & other)
216 requires ((skills & strong_type_skill::modulo) != strong_type_skill::none)
219 return derived_t{
get() % other.get()};
229 constexpr derived_t operator&(strong_type
const & other)
232 requires ((skills & strong_type_skill::bitwise_and) != strong_type_skill::none)
235 return derived_t{
get() & other.get()};
239 constexpr derived_t
operator|(strong_type
const & other)
241 requires ((skills & strong_type_skill::bitwise_or) != strong_type_skill::none)
244 return derived_t{
get() | other.get()};
248 constexpr derived_t operator^(strong_type
const & other)
250 requires ((skills & strong_type_skill::bitwise_xor) != strong_type_skill::none)
253 return derived_t{
get() ^ other.get()};
257 constexpr derived_t operator~()
259 requires ((skills & strong_type_skill::bitwise_not) != strong_type_skill::none)
262 return derived_t{~
get()};
272 constexpr derived_t
operator<<(strong_type
const & other)
275 requires ((skills & strong_type_skill::bitwise_lshift) != strong_type_skill::none)
278 return derived_t{
get() << other.get()};
282 template <std::
integral
integral_t>
283 constexpr derived_t
operator<<(integral_t
const shift)
285 requires ((skills & strong_type_skill::bitwise_lshift) != strong_type_skill::none)
288 return derived_t{
get() << shift};
292 constexpr derived_t operator>>(strong_type
const & other)
294 requires ((skills & strong_type_skill::bitwise_rshift) != strong_type_skill::none)
297 return derived_t{
get() >> other.get()};
301 template <std::
integral
integral_t>
302 constexpr derived_t operator>>(integral_t
const shift)
304 requires ((skills & strong_type_skill::bitwise_rshift) != strong_type_skill::none)
307 return derived_t{
get() >> shift};
317 constexpr
bool operator&&(strong_type
const & other)
320 requires ((skills & strong_type_skill::logical_and) != strong_type_skill::none)
323 return get() && other.get();
327 constexpr
bool operator||(strong_type
const & other)
329 requires ((skills & strong_type_skill::logical_or) != strong_type_skill::none)
332 return get() || other.get();
336 constexpr
bool operator!()
338 requires ((skills & strong_type_skill::logical_not) != strong_type_skill::none)
350 constexpr derived_t & operator++()
353 requires ((skills & strong_type_skill::increment) != strong_type_skill::none)
357 return static_cast<derived_t &>(*
this);
361 constexpr derived_t operator++(
int)
363 requires ((skills & strong_type_skill::increment) != strong_type_skill::none)
366 derived_t tmp{
get()};
372 constexpr derived_t & operator--()
374 requires ((skills & strong_type_skill::decrement) != strong_type_skill::none)
378 return static_cast<derived_t &>(*
this);
382 constexpr derived_t operator--(
int)
384 requires ((skills & strong_type_skill::decrement) != strong_type_skill::none)
387 derived_t tmp{
get()};
398 explicit constexpr
operator value_t() const
401 requires ((skills & strong_type_skill::convert) != strong_type_skill::none)