SeqAn3  3.0.1
The Modern C++ library for sequence analysis.
strong_type.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2020, 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 <type_traits>
16 
19 #include <seqan3/std/concepts>
20 
21 namespace seqan3::detail
22 {
23 
27 enum struct strong_type_skill
28 {
29  none = 0,
30  add = 1 << 0,
31  subtract = 1 << 1,
32  multiply = 1 << 2,
33  divide = 1 << 3,
34  modulo = 1 << 4,
35  bitwise_and = 1 << 5,
36  bitwise_or = 1 << 6,
37  bitwise_xor = 1 << 7,
38  bitwise_not = 1 << 8,
39  bitwise_lshift = 1 << 9,
40  bitwise_rshift = 1 << 10,
41  logical_and = 1 << 11,
42  logical_or = 1 << 12,
43  logical_not = 1 << 13,
44  increment = 1 << 14,
45  decrement = 1 << 15,
46  convert = 1 << 16,
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
52 };
53 } //namespace seqan3::detail
54 
55 namespace seqan3
56 {
58 template <>
59 constexpr bool add_enum_bitwise_operators<seqan3::detail::strong_type_skill> = true;
61 }
62 
63 namespace seqan3::detail
64 {
65 
114 template <typename value_t, typename derived_t, strong_type_skill skills = strong_type_skill::none>
115 class strong_type
116 {
117 public:
118 
120  using value_type = value_t;
121 
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;
132 
134  constexpr explicit strong_type(value_t _value) : value(std::move(_value))
135  {}
137 
141  constexpr value_t & get() & noexcept
143  {
144  return value;
145  }
146 
148  constexpr value_t const & get() const & noexcept
149  {
150  return value;
151  }
152 
154  constexpr value_t && get() && noexcept
155  {
156  return std::move(value);
157  }
158 
160  constexpr value_t const && get() const && noexcept
161  {
162  return std::move(value);
163  }
165 
171  constexpr derived_t operator+(strong_type const & other)
174  requires ((skills & strong_type_skill::add) != strong_type_skill::none)
176  {
177  return derived_t{get() + other.get()};
178  }
179 
181  constexpr derived_t operator-(strong_type const & other)
183  requires ((skills & strong_type_skill::subtract) != strong_type_skill::none)
185  {
186  return derived_t{get() - other.get()};
187  }
189 
195  constexpr derived_t operator*(strong_type const & other)
198  requires ((skills & strong_type_skill::multiply) != strong_type_skill::none)
200  {
201  return derived_t{get() * other.get()};
202  }
203 
205  constexpr derived_t operator/(strong_type const & other)
207  requires ((skills & strong_type_skill::divide) != strong_type_skill::none)
209  {
210  return derived_t{get() / other.get()};
211  }
212 
214  constexpr derived_t operator%(strong_type const & other)
216  requires ((skills & strong_type_skill::modulo) != strong_type_skill::none)
218  {
219  return derived_t{get() % other.get()};
220  }
222 
229  constexpr derived_t operator&(strong_type const & other)
232  requires ((skills & strong_type_skill::bitwise_and) != strong_type_skill::none)
234  {
235  return derived_t{get() & other.get()};
236  }
237 
239  constexpr derived_t operator|(strong_type const & other)
241  requires ((skills & strong_type_skill::bitwise_or) != strong_type_skill::none)
243  {
244  return derived_t{get() | other.get()};
245  }
246 
248  constexpr derived_t operator^(strong_type const & other)
250  requires ((skills & strong_type_skill::bitwise_xor) != strong_type_skill::none)
252  {
253  return derived_t{get() ^ other.get()};
254  }
255 
257  constexpr derived_t operator~()
259  requires ((skills & strong_type_skill::bitwise_not) != strong_type_skill::none)
261  {
262  return derived_t{~get()};
263  }
265 
272  constexpr derived_t operator<<(strong_type const & other)
275  requires ((skills & strong_type_skill::bitwise_lshift) != strong_type_skill::none)
277  {
278  return derived_t{get() << other.get()};
279  }
280 
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)
287  {
288  return derived_t{get() << shift};
289  }
290 
292  constexpr derived_t operator>>(strong_type const & other)
294  requires ((skills & strong_type_skill::bitwise_rshift) != strong_type_skill::none)
296  {
297  return derived_t{get() >> other.get()};
298  }
299 
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)
306  {
307  return derived_t{get() >> shift};
308  }
310 
317  constexpr bool operator&&(strong_type const & other)
320  requires ((skills & strong_type_skill::logical_and) != strong_type_skill::none)
322  {
323  return get() && other.get();
324  }
325 
327  constexpr bool operator||(strong_type const & other)
329  requires ((skills & strong_type_skill::logical_or) != strong_type_skill::none)
331  {
332  return get() || other.get();
333  }
334 
336  constexpr bool operator!()
338  requires ((skills & strong_type_skill::logical_not) != strong_type_skill::none)
340  {
341  return !get();
342  }
344 
350  constexpr derived_t & operator++()
353  requires ((skills & strong_type_skill::increment) != strong_type_skill::none)
355  {
356  ++get();
357  return static_cast<derived_t &>(*this);
358  }
359 
361  constexpr derived_t operator++(int)
363  requires ((skills & strong_type_skill::increment) != strong_type_skill::none)
365  {
366  derived_t tmp{get()};
367  ++get();
368  return tmp;
369  }
370 
372  constexpr derived_t & operator--()
374  requires ((skills & strong_type_skill::decrement) != strong_type_skill::none)
376  {
377  --get();
378  return static_cast<derived_t &>(*this);
379  }
380 
382  constexpr derived_t operator--(int)
384  requires ((skills & strong_type_skill::decrement) != strong_type_skill::none)
386  {
387  derived_t tmp{get()};
388  --get();
389  return tmp;
390  }
392 
398  explicit constexpr operator value_t() const
401  requires ((skills & strong_type_skill::convert) != strong_type_skill::none)
403  {
404  return get();
405  }
407 private:
409  value_t value;
410 };
411 
412 } // namespace seqan3::detail
basic.hpp
Provides various type traits on generic types.
seqan3::views::move
const auto move
A view that turns lvalue-references into rvalue-references.
Definition: move.hpp:68
seqan3::operator|
auto operator|(validator1_type &&vali1, validator2_type &&vali2)
Enables the chaining of validators.
Definition: validators.hpp:1023
concepts
The Concepts library.
seqan3
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:36
add_enum_bitwise_operators.hpp
Provides seqan3::add_enum_bitwise_operators.
seqan3::operator<<
debug_stream_type< char_t > & operator<<(debug_stream_type< char_t > &stream, tuple_t const &alignment)
Stream operator for alignments, which are represented as tuples of aligned sequences.
Definition: aligned_sequence_concept.hpp:559
std
SeqAn specific customisations in the standard namespace.
seqan3::views::convert
const auto convert
A view that converts each element in the input range (implicitly or via static_cast).
Definition: convert.hpp:71
seqan3::none
No flag is set.
Definition: debug_stream_type.hpp:30
seqan3::get
constexpr const auto & 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:576