]> git.donarmstrong.com Git - lilypond.git/blob - flower/include/interval.hh
c2d012c4f165b7d00e299650c157604d1a5194d6
[lilypond.git] / flower / include / interval.hh
1 /*
2   interval.hh -- part of flowerlib
3   
4   (c) 1996--2004 Han-Wen Nienhuys
5 */
6
7 #ifndef INTERVAL_HH
8 #define INTERVAL_HH
9
10 #include <assert.h> 
11 #include "flower-proto.hh"
12 #include "real.hh"
13 #include "drul-array.hh"
14
15 /* A T interval.  This represents the closed interval [left,right].
16    No invariants.  T must be a totally ordered ring (with division, anyway ..)
17    At instantiation, the function infinity () has to be defined explicitely. */
18 template<class T>
19 struct Interval_t : public Drul_array<T>
20 {
21   Drul_array<T>::elem;
22   Drul_array<T>::elem_ref;
23
24   static T infinity ();
25   static String T_to_string (T arg);
26   T center () const;
27   void translate (T t)
28     {
29       elem_ref (LEFT) += t;
30       elem_ref (RIGHT) += t;
31     }
32   void widen (T t)
33   {
34     elem_ref (LEFT) -= t;
35     elem_ref (RIGHT) += t;    
36   }
37   
38   T distance (T t) const
39   {
40     if (t > elem (RIGHT))
41       return T (t - elem (RIGHT));
42     else if (t < elem (LEFT))
43       return T (elem (LEFT) - t);
44     else
45       return T (0);
46   }
47   /**
48     PRE
49     *this and h are comparable
50     */
51   void unite (Interval_t<T> h);
52   void intersect (Interval_t<T> h);
53   void add_point (T p)
54   {
55     elem_ref(LEFT) = elem (LEFT) <? p;
56     elem_ref(RIGHT) = elem (RIGHT) >? p;
57   }
58   T length () const;
59   T delta () const;
60   void set_empty ();
61   void set_full ();
62
63   /*
64     TODO: strip hungarian suffix.
65    */
66   bool is_empty () const
67   {
68     return elem (LEFT) > elem (RIGHT);
69   }
70   bool superset (Interval_t<T> const&) const;
71   Interval_t ()
72   {
73     set_empty ();
74   }
75   Interval_t (T m, T M) : Drul_array<T> (m,M)
76     {
77     }
78   Interval_t<T> &operator -= (T r) {
79     *this += -r;
80     return *this;
81   }
82
83   Interval_t<T> &operator += (T r) {
84     elem_ref (LEFT) += r;
85     elem_ref (RIGHT) +=r;
86     return *this;
87   }
88   Interval_t<T> &operator *= (T r) {
89     if (!is_empty ())
90       {
91         elem_ref (LEFT) *= r;
92         elem_ref (RIGHT) *= r;
93         if (r < T (0))
94           swap();
95
96       }
97     return *this;
98   }
99
100   Real linear_combination (Real x) const
101   {
102     Drul_array<Real> da (elem (LEFT), elem (RIGHT));
103     return ::linear_combination (da, x);
104   }
105   String to_string () const;
106
107   bool contains (T r);
108   void negate ()
109   {
110     T r = -elem (LEFT);
111     T l = -elem (RIGHT);
112     elem_ref (LEFT) = l;
113     elem_ref (RIGHT) =r;
114   }
115
116   void swap ()
117   {
118     T t = elem (LEFT);
119     elem_ref (LEFT) = elem (RIGHT);
120     elem_ref (RIGHT) = t;
121   }
122 };
123
124
125 /**
126   inclusion ordering. Crash if not  comparable.
127   */
128 template<class T>
129 int Interval__compare (const Interval_t<T>&,Interval_t<T> const&);
130
131 /**
132    Inclusion ordering.  return -2 if not comparable
133  */
134 template<class T>
135 int
136 _Interval__compare (const Interval_t<T>&a,Interval_t<T> const&b);
137
138
139 /*
140   INLINE
141  */
142
143 #include "compare.hh"
144
145 TEMPLATE_INSTANTIATE_COMPARE (Interval_t<T>&, Interval__compare, template<class T>);
146
147
148 template<class T>
149 inline Interval_t<T>
150 intersection (Interval_t<T> a, Interval_t<T> const&b)
151 {
152   a.intersect (b);
153   return a;
154     
155 }
156
157 template<class T>
158 inline
159 Interval_t<T> operator + (T a,Interval_t<T> i)
160 {
161   i += a;
162   return i;
163 }
164
165 template<class T>
166 inline
167 Interval_t<T> operator - (Interval_t<T> i, T a)
168 {
169   i += -a;
170   return i;
171 }
172
173 template<class T>
174 inline
175 Interval_t<T> operator - (T a,Interval_t<T> i)
176 {
177   i.negate ();
178   i += a;
179   return i;
180 }
181
182 template<class T>
183 inline
184 Interval_t<T> operator + (Interval_t<T> i,T a){
185   return a+i;
186 }
187
188 template<class T>
189 inline
190 Interval_t<T> operator * (T a,Interval_t<T> i)
191 {
192   i *= a;
193   return i;
194 }
195
196 template<class T>
197 inline
198 Interval_t<T> operator * (Interval_t<T> i,T a){
199   return a*i;
200 }
201
202
203 template<class T>
204 inline T
205 Interval_t<T>::center () const
206 {
207   assert (!is_empty ());
208   return (elem (LEFT) + elem (RIGHT)) / T (2);
209 }
210
211 // again? see flower-proto.hh
212 typedef Interval_t<Real> Interval;
213 typedef Interval_t<int> Slice;  // weird name
214
215
216 #endif // INTERVAL_HH
217