1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3 
4   Copyright (C) 1996--2020 Han-Wen Nienhuys <hanwen@xs4all.nl>
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_TCC
21 #define INTERVAL_TCC
22 
23 #include <cassert>
24 
25 #include "interval.hh"
26 #include "std-string.hh"
27 
28 // MacOS 10.3 problems:
29 // #include <cmath>
30 
31 template<class T>
32 int
_Interval__compare(const Interval_t<T> & a,Interval_t<T> const & b)33 _Interval__compare (const Interval_t<T> &a, Interval_t<T> const &b)
34 {
35   if (a.at (LEFT) == b.at (LEFT) && a.at (RIGHT) == b.at (RIGHT))
36     return 0;
37 
38   if (a.at (LEFT) <= b.at (LEFT) && a.at (RIGHT) >= b.at (RIGHT))
39     return 1;
40 
41   if (a.at (LEFT) >= b.at (LEFT) && a.at (RIGHT) <= b.at (RIGHT))
42     return -1;
43 
44   return -2;
45 }
46 
47 template<class T>
48 int
Interval__compare(Interval_t<T> const & a,Interval_t<T> const & b)49 Interval__compare (Interval_t<T> const &a, Interval_t<T> const &b)
50 {
51   int i = _Interval__compare (a, b);
52   if (i < -1)
53     assert (false);
54   return i;
55 }
56 
57 template<class T>
58 void
set_empty()59 Interval_t<T>::set_empty ()
60 {
61   at (LEFT) = (T) infinity ();
62   at (RIGHT) = (T) - infinity ();
63 }
64 
65 template<class T>
66 void
set_full()67 Interval_t<T>::set_full ()
68 {
69   at (LEFT) = (T) - infinity ();
70   at (RIGHT) = (T) infinity ();
71 }
72 
73 template<class T>
74 T
length() const75 Interval_t<T>::length () const
76 {
77   if (at (RIGHT) <= at (LEFT))
78     return 0;
79   else
80     return at (RIGHT) - at (LEFT);
81 }
82 
83 /* smallest Interval which includes *this and #h#  */
84 template<class T>
85 void
unite(Interval_t<T> h)86 Interval_t<T>::unite (Interval_t<T> h)
87 {
88   at (LEFT) = std::min (h.at (LEFT), at (LEFT));
89   at (RIGHT) = std::max (h.at (RIGHT), at (RIGHT));
90 }
91 
92 template<class T>
93 void
intersect(Interval_t<T> h)94 Interval_t<T>::intersect (Interval_t<T> h)
95 {
96   at (LEFT) = std::max (h.at (LEFT), at (LEFT));
97   at (RIGHT) = std::min (h.at (RIGHT), at (RIGHT));
98 }
99 
100 template<class T>
101 std::string
to_string() const102 Interval_t<T>::to_string () const
103 {
104   if (is_empty ())
105     return "[empty]";
106 
107   // Rely on argument-dependent lookup to find to_string for classes,
108   // and import std::to_string to support basic types.
109   using std::to_string;
110   std::string s ("[");
111   return s + to_string (at (LEFT)) + ',' + to_string (at (RIGHT)) + ']';
112 }
113 
114 template<class T>
115 bool
contains(T r) const116 Interval_t<T>::contains (T r) const
117 {
118   return r >= at (LEFT) && r <= at (RIGHT);
119 }
120 
121 #define INTERVAL__INSTANTIATE(T) struct Interval_t<T>;                  \
122   template int Interval__compare (const Interval_t<T> &, Interval_t<T> const &)
123 
124 #endif // INTERVAL_TCC
125