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