sequencer
fixed_point_type.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <cstdint>
4 #include <limits>
5 #include <ostream>
6 
7 namespace sequencer
8 {
9  template < class T >
10  constexpr std::int64_t constexpr_round( T a ) noexcept
11  {
12  return ( a > 0 ) ? std::int64_t( a + T{0.5} ) : std::int64_t( a - T{0.5} );
13  }
14 
15  template < int ticks_per_unit >
17  {
18  public:
19  using rep = double;
20  using internal_rep = std::int64_t;
21  static constexpr rep eps = 1.0 / ticks_per_unit;
22 
23  constexpr explicit fixed_point_type( rep value = 0 ) noexcept
24  : count_( constexpr_round( value / eps ) + std::numeric_limits< rep >::epsilon() )
25  {
26  }
27 
28  constexpr double to_double() const noexcept
29  {
30  return count_ * eps;
31  }
32 
33  constexpr fixed_point_type& operator+=( fixed_point_type other ) noexcept
34  {
35  count_ += other.count_;
36  return *this;
37  }
38 
39  constexpr fixed_point_type operator-() const noexcept
40  {
41  return fixed_point_type{-to_double()};
42  }
43 
44  constexpr bool operator==( fixed_point_type other ) const noexcept
45  {
46  return count_ == other.count_;
47  }
48 
49  constexpr bool operator!=( fixed_point_type other ) const noexcept
50  {
51  return !( *this == other );
52  }
53 
54  constexpr bool operator<( fixed_point_type other ) const noexcept
55  {
56  return count_ < other.count_;
57  }
58 
59  constexpr bool operator<=( fixed_point_type other ) const noexcept
60  {
61  return count_ <= other.count_;
62  }
63 
64  static constexpr fixed_point_type from_count( internal_rep count ) noexcept
65  {
66  return fixed_point_type( count * eps );
67  }
68 
69  static constexpr fixed_point_type max() noexcept
70  {
71  return from_count( std::numeric_limits< internal_rep >::max() - ticks_per_unit );
72  }
73 
74  private:
75  internal_rep count_;
76  };
77 
78  template < int ticks_per_unit >
81  {
82  return lhs += rhs;
83  }
84 
85  template < int ticks_per_unit >
86  std::ostream& operator<<( std::ostream& os, fixed_point_type< ticks_per_unit > value )
87  {
88  return os << value.to_double();
89  }
90 } // namespace sequencer
91 
92 namespace std
93 {
94  template < int ticks_per_unit >
95  class numeric_limits< sequencer::fixed_point_type< ticks_per_unit > >
96  {
97  public:
99  {
101  }
102  };
103 } // namespace std
static constexpr sequencer::fixed_point_type< ticks_per_unit > max() noexcept
Definition: fixed_point_type.hpp:98
constexpr bool operator!=(fixed_point_type other) const noexcept
Definition: fixed_point_type.hpp:49
constexpr fixed_point_type operator-() const noexcept
Definition: fixed_point_type.hpp:39
Definition: beat_duration.hpp:106
constexpr double to_double() const noexcept
Definition: fixed_point_type.hpp:28
double rep
Definition: fixed_point_type.hpp:19
static constexpr fixed_point_type max() noexcept
Definition: fixed_point_type.hpp:69
constexpr beat_duration operator+(beat_duration lhs, beat_duration rhs) noexcept
Definition: beat_duration.hpp:60
constexpr fixed_point_type & operator+=(fixed_point_type other) noexcept
Definition: fixed_point_type.hpp:33
constexpr bool operator<(fixed_point_type other) const noexcept
Definition: fixed_point_type.hpp:54
static constexpr rep eps
Definition: fixed_point_type.hpp:21
Definition: fixed_point_type.hpp:16
static constexpr fixed_point_type from_count(internal_rep count) noexcept
Definition: fixed_point_type.hpp:64
constexpr std::int64_t constexpr_round(T a) noexcept
Definition: fixed_point_type.hpp:10
constexpr bool operator<=(fixed_point_type other) const noexcept
Definition: fixed_point_type.hpp:59
std::int64_t internal_rep
Definition: fixed_point_type.hpp:20
constexpr fixed_point_type(rep value=0) noexcept
Definition: fixed_point_type.hpp:23
constexpr bool operator==(fixed_point_type other) const noexcept
Definition: fixed_point_type.hpp:44