1 #ifndef CoCoA_VectorOps_H
2 #define CoCoA_VectorOps_H
3 
4 //   Copyright (c)  2005,2006,2009  John Abbott
5 
6 //   This file is part of the source of CoCoALib, the CoCoA Library.
7 
8 //   CoCoALib is free software: you can redistribute it and/or modify
9 //   it under the terms of the GNU General Public License as published by
10 //   the Free Software Foundation, either version 3 of the License, or
11 //   (at your option) any later version.
12 
13 //   CoCoALib is distributed in the hope that it will be useful,
14 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 //   GNU General Public License for more details.
17 
18 //   You should have received a copy of the GNU General Public License
19 //   along with CoCoALib.  If not, see <http://www.gnu.org/licenses/>.
20 
21 
22 // This contains sundry things which may eventually become stable parts of
23 // the CoCoA library.
24 
25 
26 #include "CoCoA/error.H"
27 
28 #include <algorithm>
29 //using std::for_each;
30 //using std::find_if;
31 #include <iostream>
32 #include <list>
33 // using std::list
34 #include <vector>
35 // using std::vector;
36 
37 namespace CoCoA
38 {
39 
40   ////////////////////////////////////////////////////////////
41   // Basic pseudo-constructors
42 
43 //   template <typename T>
44 //   inline std::vector<T> CoCoAVector(const T& a)
45 //   { return std::vector<T>(1,a); }
46 
47 //   template <typename T>
48 //   inline std::vector<T> CoCoAVector(const T& a, const T& b)
49 //   { std::vector<T> v(1,a); v.push_back(b); return v; }
50 
51 //   template <typename T>
52 //   inline std::vector<T> CoCoAVector(const T& a, const T& b, const T& c)
53 //   { std::vector<T> v(1,a); v.push_back(b); v.push_back(c); return v; }
54 
55 //   template <typename T>
56 //   inline std::vector<T> CoCoAVector(const T& a,const T& b,const T& c,const T& d)
57 //   { std::vector<T> v(1,a);v.push_back(b);v.push_back(c);v.push_back(d); return v;}
58 
59   ///////////////////////////////////////////////////////
60   // Functions for printing vectors/lists/etc.
61 
62   // LLVM 6.0 (MacOS 10.10) needs this fwd decl
63   template <typename FwdIterator_t>
64   void OutputRange(std::ostream& out, FwdIterator_t start, const FwdIterator_t& end);
65 
66 
67   // Use cout << v syntax to print out a std::vector<T> of printable values.
68   template <typename T>
69   inline std::ostream& operator<<(std::ostream& out, const std::vector<T>& v)
70   {
71     OutputRange(out, v.begin(), v.end());
72     return out;
73   }
74 
75   // Use cout << l syntax to print out a std::list<T> of printable values.
76   template <typename T>
77   inline std::ostream& operator<<(std::ostream& out, const std::list<T>& v)
78   {
79     OutputRange(out, v.begin(), v.end());
80     return out;
81   }
82 
83   // This prints out the elements (of a list or vector) in a given range.
84   // The empty list appears as []; otherwise ",  " separated elements
85   // between "[" and "]".
86   // NOTE: This template fn is not intended for public use!
87   template <typename FwdIterator_t>
OutputRange(std::ostream & out,FwdIterator_t start,const FwdIterator_t & end)88   void OutputRange(std::ostream& out, FwdIterator_t start, const FwdIterator_t& end)
89   {
90     if (!out) return;
91     if (start == end) { out << "[]"; return; }
92     out << "[" << *start;
93     while (++start != end)
94       out << ",  " << *start;
95     out << "]";
96   }
97 
98 
99   ////////////////////////////////////////////////////////////
100   // Functions for computing products of lists and vectors.
101 
102   // This class is simply to permit use of std::for_each.
103   template <typename arith_t>
104   class SeqProd
105   {
106   public:
SeqProd(const arith_t & InitialValue)107     SeqProd(const arith_t& InitialValue): myProdSoFar(InitialValue) {}
108     // Default copy ctor, assignment, and dtor are all OK.
operator()109     void operator()(const arith_t& NextValue) { myProdSoFar *= NextValue; }
myCurrentValue()110     const arith_t& myCurrentValue() const { return myProdSoFar; }
111   private:
112     arith_t myProdSoFar;
113   };
114 
115   template <typename InputIterator, typename arith_t>
product(InputIterator begin,InputIterator end,const arith_t & InitialValue)116   arith_t product(InputIterator begin, InputIterator end, const arith_t& InitialValue)
117   {
118     return std::for_each(begin, end, SeqProd<arith_t>(InitialValue)).myCurrentValue();
119   }
120 
121   template <typename ListOrVector>
product(const ListOrVector & V)122   typename ListOrVector::value_type product(const ListOrVector& V)
123   {
124     if (V.empty()) CoCoA_ERROR(ERR::Empty, "product(L)");
125     return product(++V.begin(), V.end(), V.front());
126   }
127 
128 
129   ////////////////////////////////////////////////////////////
130   // Functions for computing sums of lists and vectors.
131 
132   // This class is simply to permit use of for_each.
133   template <typename arith_t>
134   class SeqSum
135   {
136   public:
SeqSum(const arith_t & InitialValue)137     SeqSum(const arith_t& InitialValue): mySumSoFar(InitialValue) {}
138     // Default copy ctor, assignment, and dtor are all OK.
operator()139     void operator()(const arith_t& NextValue) { mySumSoFar += NextValue; }
myCurrentValue()140     const arith_t& myCurrentValue() const { return mySumSoFar; }
141   private:
142     arith_t mySumSoFar;
143   };
144 
145   template <typename InputIterator, typename arith_t>
sum(InputIterator begin,InputIterator end,const arith_t & InitialValue)146   arith_t sum(InputIterator begin, InputIterator end, const arith_t& InitialValue)
147   {
148     return std::for_each(begin, end, SeqSum<arith_t>(InitialValue)).myCurrentValue();
149   }
150 
151   template <typename ListOrVector>
sum(const ListOrVector & V)152   typename ListOrVector::value_type sum(const ListOrVector& V)
153   {
154     if (V.empty()) CoCoA_ERROR(ERR::Empty, "sum(L)");
155     return sum(++V.begin(), V.end(), V.front());
156   }
157 
158 
159 ////////////////////////////////////////////////////////////
160 // Functions for checking all elements have the same owner
161 
162 // This class is simply to permit use of find_if.
163   template <class elem_t>
164   class HasDifferentOwner
165   {
166   public:
HasDifferentOwner(const elem_t & x)167     HasDifferentOwner(const elem_t& x): myValue(x) {};
168     // Default copy ctor, assignment, and dtor are all OK.
operator()169     bool operator() (const elem_t& x) const { return owner(x) != owner(myValue); }
170   private:
171     const elem_t& myValue;
172   };
173 
174   template <typename container>
HasUniqueOwner(const container & v)175   bool HasUniqueOwner(const container& v)
176   {
177     typedef typename container::value_type elem_t;
178     if (v.empty()) return true;
179     return v.end() ==
180       find_if(++v.begin(), v.end(), HasDifferentOwner<elem_t>(v.front()));
181   }
182 
183 
184 //////////////////////////////////////////////////////////////////
185 //  3-way comparison
186 
187 //   // Generic 3-way comparison function: assumes operator< is defined.
188 //   // Result is <0 =0 or >0 according as a<b, a==b, a>b.
189 //   template <typename T1, typename T2>
190 //   inline int cmp(const T1& a, const T2& b)
191 //   {
192 //     if (a < b) return -1;
193 //     if (b < a) return 1;
194 //     return 0;
195 //   }
196 
197   // LexCmp3 3-way lex comparison.  I think this ought to be in the STL.
198   // Result is <0, =0, or >0 according as begin1..end1 < = > begin2..end2
199   // Assumes existence of fn cmp for single elements.
200   template <class InputIterator1, class InputIterator2>
LexCmp3(InputIterator1 begin1,InputIterator1 end1,InputIterator2 begin2,InputIterator2 end2)201   inline int LexCmp3(InputIterator1 begin1, InputIterator1 end1,
202                      InputIterator2 begin2, InputIterator2 end2)
203   {
204     while (begin1 != end1 && begin2 != end2)
205     {
206       const int sign = cmp(*begin1, *begin2);
207       if (sign != 0) return sign;
208       ++begin1;
209       ++begin2;
210     }
211     if (begin1 != end1) return 1;
212     if (begin2 != end2) return -1;
213     return 0;
214   }
215 
216 
217   // // This function object class taken from Meyers's "Effective STL", page 38 (first ed.)
218   // // It can be used to delete all the elements in an STL container of pointers.
219   // struct DeleteObject
220   // {
221   //   template<typename T> void operator()(const T* ptr) const
222   //   {
223   //     delete ptr;
224   //   }
225   // };
226 
227 
228 } // end of namespace CoCoA
229 
230 
231 
232 // RCS header/log in the next few lines.
233 // $Header: /Volumes/Home_1/cocoa/cvs-repository/CoCoALib-0.99/include/CoCoA/VectorOps.H,v 1.2 2020/01/13 17:41:50 bigatti Exp $
234 // $Log: VectorOps.H,v $
235 // Revision 1.2  2020/01/13 17:41:50  bigatti
236 // -- removed CoCoAVector
237 //
238 // Revision 1.1  2018/05/17 15:24:31  bigatti
239 // -- renamed VectorOperations --> VectorOps
240 //
241 // Revision 1.5  2016/11/23 15:35:47  abbott
242 // Summary: Added short-cut for "dead" ostream
243 //
244 // Revision 1.4  2014/12/02 14:10:46  bigatti
245 // -- basic pseudo-ctors for CoCoAVector
246 //
247 // Revision 1.3  2014/09/26 14:47:36  abbott
248 // Summary: Moved defn of OutputRange; added fwd decl, to keep LLVM compiler quiet
249 // Author: JAA
250 //
251 // Revision 1.2  2014/07/31 14:47:28  abbott
252 // Summary: Corrected copyright date
253 // Author: JAA
254 //
255 // Revision 1.1  2014/07/31 14:43:43  abbott
256 // Summary: Merged io.H and UtilsTemplate.H into this file
257 // Author: JAA
258 //
259 // Revision 1.5  2014/07/31 13:03:31  abbott
260 // Summary: Removed needless include of <vector>
261 // Author: JAA
262 //
263 // Revision 1.4  2014/07/15 16:50:29  abbott
264 // Summary: Commented out DeleteObject -- never used by anyone
265 // Author: JAA
266 //
267 // Revision 1.3  2014/07/14 16:04:43  abbott
268 // Summary: HasUniqueOwner should now work for any container
269 // Author: JAA
270 //
271 // Revision 1.2  2014/07/14 15:04:46  abbott
272 // Summary: Moved LexCmp3 here from utils.H; minor cleaning
273 // Author: JAA
274 //
275 // Revision 1.1  2014/07/14 14:22:07  abbott
276 // Summary: Renamed from tmp.H
277 // Author: JAA
278 //
279 // Revision 1.6  2011/02/10 15:25:39  bigatti
280 // -- fixed HasUniqueOwner for empty lists
281 //
282 // Revision 1.5  2009/11/20 15:52:43  bigatti
283 // -- fixed string
284 //
285 // Revision 1.4  2009/07/24 15:15:58  bigatti
286 // -- unified sum (and product) for C++ lists and vectors
287 // -- added: HasUniqueOwner for vector of elements with function "owner"
288 //
289 // Revision 1.3  2009/05/20 14:26:19  abbott
290 // CVS says something has changed, but I cannot see what (maybe whitespace?).
291 //
292 // Revision 1.2  2007/10/30 17:14:11  abbott
293 // Changed licence from GPL-2 only to GPL-3 or later.
294 // New version for such an important change.
295 //
296 // Revision 1.1.1.1  2007/03/09 15:16:11  abbott
297 // Imported files
298 //
299 // Revision 1.3  2006/12/06 17:18:40  cocoa
300 // -- removed #include "config.H"
301 //
302 // Revision 1.2  2006/10/06 14:04:15  cocoa
303 // Corrected position of #ifndef in header files.
304 // Separated CoCoA_ASSERT into assert.H from config.H;
305 // many minor consequential changes (have to #include assert.H).
306 // A little tidying of #include directives (esp. in Max's code).
307 //
308 // Revision 1.1.1.1  2006/05/30 11:39:37  cocoa
309 // Imported files
310 //
311 // Revision 1.3  2006/03/27 16:15:39  cocoa
312 // Checking in functions for printing lists and vectors of things,
313 // so that GPoly.C will compile.  Will reorganize things another day.
314 //
315 // Revision 1.2  2006/03/27 12:21:25  cocoa
316 // Minor silly changes to reduce number of complaints from some compiler or other.
317 //
318 // Revision 1.1  2006/01/20 17:44:20  cocoa
319 // Friday afternoon check-in: you have been warned!
320 // Fixed ref counting bug in SmartPtrIRC.
321 // Added sum/product functions in tmp.H.
322 // Minor tidying here and there.
323 //
324 
325 #endif
326