]> git.donarmstrong.com Git - lilypond.git/blob - flower/include/interval.hh
Refactor pure-height calculations.
[lilypond.git] / flower / include / interval.hh
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 1996--2010 Han-Wen Nienhuys
5
6   LilyPond is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation, either version 3 of the License, or
9   (at your option) any later version.
10
11   LilyPond is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #ifndef INTERVAL_HH
21 #define INTERVAL_HH
22
23 #include <math.h>
24
25 #include "flower-proto.hh"
26 #include "drul-array.hh"
27
28 /* A T interval.  This represents the closed interval [left,right].
29    No invariants.  T must be a totally ordered ring (with division, anyway ..)
30    At instantiation, the function infinity () has to be defined explicitly. */
31 template<class T>
32 struct Interval_t : public Drul_array<T>
33 {
34   Drul_array<T>::at;
35
36   static T infinity ();
37   static string T_to_string (T arg);
38   T center () const;
39   void translate (T t)
40   {
41     at (LEFT) += t;
42     at (RIGHT) += t;
43   }
44   void widen (T t)
45   {
46     at (LEFT) -= t;
47     at (RIGHT) += t;
48   }
49
50   T distance (T t) const
51   {
52     if (t > at (RIGHT))
53       return T (t - at (RIGHT));
54     else if (t < at (LEFT))
55       return T (at (LEFT) - t);
56     else
57       return T (0);
58   }
59   /**
60      PRE
61      *this and h are comparable
62      */
63   void unite (Interval_t<T> h);
64   void intersect (Interval_t<T> h);
65   void add_point (T p)
66   {
67     at (LEFT) = min (at (LEFT), p);
68     at (RIGHT) = max (at (RIGHT), p);
69   }
70   T length () const;
71   T delta () const;
72   void set_empty ();
73   void set_full ();
74
75   void unite_disjoint (Interval_t<T> h, T padding, Direction d);
76
77   bool is_empty () const
78   {
79     return at (LEFT) > at (RIGHT);
80   }
81   bool superset (Interval_t<T> const &) const;
82   Interval_t ()
83   {
84     set_empty ();
85   }
86   Interval_t (Drul_array<T> const &src)
87     : Drul_array<T> (src)
88   {
89   }
90
91   Interval_t (T m, T M) : Drul_array<T> (m, M)
92   {
93   }
94   Interval_t<T> &operator -= (T r)
95   {
96     *this += -r;
97     return *this;
98   }
99
100   Interval_t<T> &operator += (T r)
101   {
102     at (LEFT) += r;
103     at (RIGHT) += r;
104     return *this;
105   }
106   Interval_t<T> &operator *= (T r)
107   {
108     if (!is_empty ())
109       {
110         at (LEFT) *= r;
111         at (RIGHT) *= r;
112         if (r < T (0))
113           swap ();
114       }
115     return *this;
116   }
117
118   Real linear_combination (Real x) const;
119   string to_string () const;
120
121   bool contains (T r) const;
122   void negate ()
123   {
124     T r = -at (LEFT);
125     T l = -at (RIGHT);
126     at (LEFT) = l;
127     at (RIGHT) = r;
128   }
129
130   void swap ()
131   {
132     T t = at (LEFT);
133     at (LEFT) = at (RIGHT);
134     at (RIGHT) = t;
135   }
136
137   static bool left_less (Interval_t<T> const &a, Interval_t<T> const &b)
138   {
139     return a[LEFT] < b[LEFT];
140   }
141 };
142
143 /**
144    inclusion ordering. Crash if not  comparable.
145 */
146 template<class T>
147 int Interval__compare (const Interval_t<T> &, Interval_t<T> const &);
148
149 /**
150    Inclusion ordering.  return -2 if not comparable
151 */
152 template<class T>
153 int
154 _Interval__compare (const Interval_t<T> &a, Interval_t<T> const &b);
155
156 /*
157   INLINE
158 */
159
160 #include "compare.hh"
161
162 TEMPLATE_INSTANTIATE_COMPARE (Interval_t<T> &, Interval__compare, template<class T>);
163
164 template<class T>
165 inline Interval_t<T>
166 intersection (Interval_t<T> a, Interval_t<T> const &b)
167 {
168   a.intersect (b);
169   return a;
170 }
171
172 template<class T>
173 inline
174 Interval_t<T> operator + (T a, Interval_t<T> i)
175 {
176   i += a;
177   return i;
178 }
179
180 template<class T>
181 inline
182 Interval_t<T> operator - (Interval_t<T> i, T a)
183 {
184   i += -a;
185   return i;
186 }
187
188 template<class T>
189 inline
190 Interval_t<T> operator - (T a, Interval_t<T> i)
191 {
192   i.negate ();
193   i += a;
194   return i;
195 }
196
197 template<class T>
198 inline
199 Interval_t<T> operator + (Interval_t<T> i, T a)
200 {
201   return a + i;
202 }
203
204 template<class T>
205 inline
206 Interval_t<T> operator * (T a, Interval_t<T> i)
207 {
208   i *= a;
209   return i;
210 }
211
212 template<class T>
213 inline
214 Interval_t<T> operator * (Interval_t<T> i, T a)
215 {
216   return a * i;
217 }
218
219 template<class T>
220 inline T
221 Interval_t<T>::center () const
222 {
223   assert (!is_empty ());
224   return (at (LEFT) + at (RIGHT)) / T (2);
225 }
226
227 typedef Interval_t<Real> Interval;
228 typedef Interval_t<int> Slice;  // weird name
229
230
231 #endif // INTERVAL_HH
232