1 /* Sparse_Row class implementation: non-inline template functions.
2    Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it>
3    Copyright (C) 2010-2016 BUGSENG srl (http://bugseng.com)
4 
5 This file is part of the Parma Polyhedra Library (PPL).
6 
7 The PPL is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 The PPL is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA.
20 
21 For the most up-to-date information see the Parma Polyhedra Library
22 site: http://bugseng.com/products/ppl/ . */
23 
24 #ifndef PPL_Sparse_Row_templates_hh
25 #define PPL_Sparse_Row_templates_hh 1
26 
27 namespace Parma_Polyhedra_Library {
28 
29 
30 template <typename Func1, typename Func2>
31 void
combine_needs_first(const Sparse_Row & y,const Func1 & f,const Func2 & g)32 Sparse_Row::combine_needs_first(const Sparse_Row& y,
33                                 const Func1& f, const Func2& g) {
34   if (this == &y) {
35     for (iterator i = begin(), i_end = end(); i != i_end; ++i) {
36       g(*i, *i);
37     }
38   }
39   else {
40     iterator i = begin();
41     // This is a const reference to an internal iterator, that is kept valid.
42     // If we just stored a copy, that would be invalidated by the calls to
43     // reset().
44     const iterator& i_end = end();
45     const_iterator j = y.begin();
46     const_iterator j_end = y.end();
47     while (i != i_end && j != j_end) {
48       if (i.index() == j.index()) {
49         g(*i, *j);
50         if (*i == 0) {
51           i = reset(i);
52         }
53         else {
54           ++i;
55         }
56         ++j;
57       }
58       else
59         if (i.index() < j.index()) {
60           f(*i);
61           if (*i == 0) {
62             i = reset(i);
63           }
64           else {
65             ++i;
66           }
67         }
68         else {
69           j = y.lower_bound(j, i.index());
70         }
71     }
72     while (i != i_end) {
73       f(*i);
74       if (*i == 0) {
75         i = reset(i);
76       }
77       else {
78         ++i;
79       }
80     }
81   }
82 }
83 
84 template <typename Func1, typename Func2>
85 void
combine_needs_second(const Sparse_Row & y,const Func1 & g,const Func2 &)86 Sparse_Row::combine_needs_second(const Sparse_Row& y,
87                                  const Func1& g,
88                                  const Func2& /* h */) {
89   iterator i = begin();
90   for (const_iterator j = y.begin(), j_end = y.end(); j != j_end; ++j) {
91     i = insert(i, j.index());
92     g(*i, *j);
93     if (*i == 0) {
94       i = reset(i);
95     }
96   }
97 }
98 
99 template <typename Func1, typename Func2, typename Func3>
100 void
combine(const Sparse_Row & y,const Func1 & f,const Func2 & g,const Func3 & h)101 Sparse_Row::combine(const Sparse_Row& y, const Func1& f,
102                     const Func2& g, const Func3& h) {
103   if (this == &y) {
104     for (iterator i = begin(), i_end = end(); i != i_end; ++i) {
105       g(*i, *i);
106     }
107   }
108   else {
109     iterator i = begin();
110     // This is a const reference to an internal iterator, that is kept valid.
111     // If we just stored a copy, that would be invalidated by the calls to
112     // reset() and insert().
113     const iterator& i_end = end();
114     const_iterator j = y.begin();
115     const_iterator j_end = y.end();
116     while (i != i_end && j != j_end) {
117       if (i.index() == j.index()) {
118         g(*i, *j);
119         if (*i == 0) {
120           i = reset(i);
121         }
122         else {
123           ++i;
124         }
125         ++j;
126       }
127       else
128         if (i.index() < j.index()) {
129           f(*i);
130           if (*i == 0) {
131             i = reset(i);
132           }
133           else {
134             ++i;
135           }
136         }
137         else {
138           PPL_ASSERT(i.index() > j.index());
139           i = insert(i, j.index());
140           h(*i, *j);
141           if (*i == 0) {
142             i = reset(i);
143           }
144           else {
145             ++i;
146           }
147           ++j;
148         }
149     }
150     PPL_ASSERT(i == i_end || j == j_end);
151     while (i != i_end) {
152       f(*i);
153       if (*i == 0) {
154         i = reset(i);
155       }
156       else {
157         ++i;
158       }
159     }
160     while (j != j_end) {
161       i = insert(i, j.index());
162       h(*i, *j);
163       if (*i == 0) {
164         i = reset(i);
165       }
166       ++j;
167     }
168   }
169 }
170 
171 } // namespace Parma_Polyhedra_Library
172 
173 #endif // !defined(PPL_Sparse_Row_templates_hh)
174