1 // -*- C++ -*- 2 // ACL:license 3 // ---------------------------------------------------------------------- 4 // This software and ancillary information (herein called "SOFTWARE") 5 // called PETE (Portable Expression Template Engine) is 6 // made available under the terms described here. The SOFTWARE has been 7 // approved for release with associated LA-CC Number LA-CC-99-5. 8 // 9 // Unless otherwise indicated, this SOFTWARE has been authored by an 10 // employee or employees of the University of California, operator of the 11 // Los Alamos National Laboratory under Contract No. W-7405-ENG-36 with 12 // the U.S. Department of Energy. The U.S. Government has rights to use, 13 // reproduce, and distribute this SOFTWARE. The public may copy, distribute, 14 // prepare derivative works and publicly display this SOFTWARE without 15 // charge, provided that this Notice and any statement of authorship are 16 // reproduced on all copies. Neither the Government nor the University 17 // makes any warranty, express or implied, or assumes any liability or 18 // responsibility for the use of this SOFTWARE. 19 // 20 // If SOFTWARE is modified to produce derivative works, such modified 21 // SOFTWARE should be clearly marked, so as not to confuse it with the 22 // version available from LANL. 23 // 24 // For more information about PETE, send e-mail to pete@acl.lanl.gov, 25 // or visit the PETE web page at http://www.acl.lanl.gov/pete/. 26 // ---------------------------------------------------------------------- 27 // ACL:license 28 29 #ifndef PETE_PETE_FUNCTORS_H 30 #define PETE_PETE_FUNCTORS_H 31 32 /////////////////////////////////////////////////////////////////////////////// 33 // 34 // WARNING: THIS FILE IS FOR INTERNAL PETE USE. DON'T INCLUDE IT YOURSELF 35 // 36 /////////////////////////////////////////////////////////////////////////////// 37 38 //----------------------------------------------------------------------------- 39 // Include files. 40 //----------------------------------------------------------------------------- 41 42 #include <iterator> 43 44 namespace qmcplusplus 45 { 46 //----------------------------------------------------------------------------- 47 // 48 // CLASS NAME 49 // LeafFunctor<LeafType, LeafTag> 50 // 51 // DESCRIPTION 52 // LeafType is the type of something at the leaf of the expression tree. 53 // LeafTag specifies the operation being applied. 54 // 55 // LeafFunctors are used by ForEach to apply operations to the leaves of the 56 // expression tree. Typical functors are evaluators, counters, etc. 57 // Users define functors for use with ForEach by specializing 58 // the struct LeafFunctor<LeafType, LeafTag> for the user defined Functor and 59 // any Leaf types that are necessary. 60 // 61 // This isn't a functor in the conventional sense since it isn't invoked 62 // operator() on a LeafFunctor object. Instead, the static apply member 63 // function is called without an object. In a lot of ways, this is better 64 // and more flexible than a regular functor. 65 // 66 // LeafFunctor specializations must define the following: 67 // 68 // typedef ... Type_t; 69 // - the return type of the functor. 70 // static Type_t apply(const LeafType &l, const LeafTag &f) {} 71 // - evaluates the functor on leaf l. 72 // 73 //----------------------------------------------------------------------------- 74 75 template<class LeafType, class LeafTag> 76 struct LeafFunctor 77 {}; 78 79 80 //----------------------------------------------------------------------------- 81 // 82 // CLASS NAMES 83 // EvalLeaf1-7, LeafFunctor<Scalar<T>, EvalLeaf1-7 > 84 // 85 // DESCRIPTION 86 // EvalLeaf1 through EvalLeaf7 are used to evaluate leaves using 1 to 7 87 // integer indices. We supply the tags and scalar versions here. Users must 88 // supply specializations for their own containers. 89 // 90 //----------------------------------------------------------------------------- 91 92 // 1D 93 94 struct EvalLeaf1 95 { 96 int i1_m; EvalLeaf1EvalLeaf197 inline EvalLeaf1(int i1) : i1_m(i1) {} val1EvalLeaf198 inline int val1() const { return i1_m; } 99 }; 100 101 template<class T> 102 struct LeafFunctor<Scalar<T>, EvalLeaf1> 103 { 104 typedef T Type_t; 105 inline static const Type_t& apply(const Scalar<T>& s, const EvalLeaf1&) { return s.value(); } 106 }; 107 108 // 2D 109 110 struct EvalLeaf2 111 { 112 int i1_m, i2_m; 113 inline EvalLeaf2(int i1, int i2) : i1_m(i1), i2_m(i2) {} 114 inline int val1() const { return i1_m; } 115 inline int val2() const { return i2_m; } 116 }; 117 118 template<class T> 119 struct LeafFunctor<Scalar<T>, EvalLeaf2> 120 { 121 typedef T Type_t; 122 inline static const Type_t& apply(const Scalar<T>& s, const EvalLeaf2&) { return s.value(); } 123 }; 124 125 // 3D 126 127 struct EvalLeaf3 128 { 129 int i1_m, i2_m, i3_m; 130 inline EvalLeaf3(int i1, int i2, int i3) : i1_m(i1), i2_m(i2), i3_m(i3) {} 131 inline int val1() const { return i1_m; } 132 inline int val2() const { return i2_m; } 133 inline int val3() const { return i3_m; } 134 }; 135 136 template<class T> 137 struct LeafFunctor<Scalar<T>, EvalLeaf3> 138 { 139 typedef T Type_t; 140 inline static const Type_t& apply(const Scalar<T>& s, const EvalLeaf3&) { return s.value(); } 141 }; 142 143 // 4D 144 145 struct EvalLeaf4 146 { 147 int i1_m, i2_m, i3_m, i4_m; 148 inline EvalLeaf4(int i1, int i2, int i3, int i4) : i1_m(i1), i2_m(i2), i3_m(i3), i4_m(i4) {} 149 inline int val1() const { return i1_m; } 150 inline int val2() const { return i2_m; } 151 inline int val3() const { return i3_m; } 152 inline int val4() const { return i4_m; } 153 }; 154 155 template<class T> 156 struct LeafFunctor<Scalar<T>, EvalLeaf4> 157 { 158 typedef T Type_t; 159 inline static const Type_t& apply(const Scalar<T>& s, const EvalLeaf4&) { return s.value(); } 160 }; 161 162 // 5D 163 164 struct EvalLeaf5 165 { 166 int i1_m, i2_m, i3_m, i4_m, i5_m; 167 inline EvalLeaf5(int i1, int i2, int i3, int i4, int i5) : i1_m(i1), i2_m(i2), i3_m(i3), i4_m(i4), i5_m(i5) {} 168 inline int val1() const { return i1_m; } 169 inline int val2() const { return i2_m; } 170 inline int val3() const { return i3_m; } 171 inline int val4() const { return i4_m; } 172 inline int val5() const { return i5_m; } 173 }; 174 175 template<class T> 176 struct LeafFunctor<Scalar<T>, EvalLeaf5> 177 { 178 typedef T Type_t; 179 inline static const Type_t& apply(const Scalar<T>& s, const EvalLeaf5&) { return s.value(); } 180 }; 181 182 // 6D 183 184 struct EvalLeaf6 185 { 186 int i1_m, i2_m, i3_m, i4_m, i5_m, i6_m; 187 inline EvalLeaf6(int i1, int i2, int i3, int i4, int i5, int i6) 188 : i1_m(i1), i2_m(i2), i3_m(i3), i4_m(i4), i5_m(i5), i6_m(i6) 189 {} 190 inline int val1() const { return i1_m; } 191 inline int val2() const { return i2_m; } 192 inline int val3() const { return i3_m; } 193 inline int val4() const { return i4_m; } 194 inline int val5() const { return i5_m; } 195 inline int val6() const { return i6_m; } 196 }; 197 198 template<class T> 199 struct LeafFunctor<Scalar<T>, EvalLeaf6> 200 { 201 typedef T Type_t; 202 inline static const Type_t& apply(const Scalar<T>& s, const EvalLeaf6&) { return s.value(); } 203 }; 204 205 // 7D 206 207 struct EvalLeaf7 208 { 209 int i1_m, i2_m, i3_m, i4_m, i5_m, i6_m, i7_m; 210 inline EvalLeaf7(int i1, int i2, int i3, int i4, int i5, int i6, int i7) 211 : i1_m(i1), i2_m(i2), i3_m(i3), i4_m(i4), i5_m(i5), i6_m(i6), i7_m(i7) 212 {} 213 inline int val1() const { return i1_m; } 214 inline int val2() const { return i2_m; } 215 inline int val3() const { return i3_m; } 216 inline int val4() const { return i4_m; } 217 inline int val5() const { return i5_m; } 218 inline int val6() const { return i6_m; } 219 inline int val7() const { return i7_m; } 220 }; 221 222 template<class T> 223 struct LeafFunctor<Scalar<T>, EvalLeaf7> 224 { 225 typedef T Type_t; 226 inline static const Type_t& apply(const Scalar<T>& s, const EvalLeaf7&) { return s.value(); } 227 }; 228 229 230 //----------------------------------------------------------------------------- 231 // 232 // CLASS NAME 233 // IncrementLeaf, LeafFunctor<{T, Scalar<T>}, IncrementLeaf > 234 // 235 // DESCRIPTION 236 // A leaf-tag and functor used to increment an iterator for scalars and 237 // leaves made up of STL iterators. 238 // 239 //----------------------------------------------------------------------------- 240 241 struct IncrementLeaf 242 {}; 243 244 template<class T> 245 struct LeafFunctor<T, IncrementLeaf> 246 { 247 typedef int Type_t; 248 inline static Type_t apply(const T& cl, const IncrementLeaf&) 249 { 250 T& l = const_cast<T&>(cl); 251 ++l; 252 return 0; 253 } 254 }; 255 256 #if defined(__MWERKS__) 257 258 // Workaround for screwy CWPro 4.1 bug. 259 260 template<class T> 261 struct LeafFunctor<const T*, IncrementLeaf> 262 { 263 typedef int Type_t; 264 inline static Type_t apply(const T*& const ci, const IncrementLeaf&) 265 { 266 T*& i = const_cast<T*&>(ci); 267 ++i; 268 return 0; 269 } 270 }; 271 272 #endif 273 274 template<class T> 275 struct LeafFunctor<Scalar<T>, IncrementLeaf> 276 { 277 typedef int Type_t; 278 inline static Type_t apply(const Scalar<T>&, const IncrementLeaf&) { return 0; } 279 }; 280 281 282 //----------------------------------------------------------------------------- 283 // 284 // CLASS NAME 285 // DecrementLeaf, LeafFunctor<{T, Scalar<T>}, DecrementLeaf > 286 // 287 // DESCRIPTION 288 // A leaf-tag and functor used to decrement an iterator for scalars and 289 // leaves made up of STL iterators. 290 // 291 //----------------------------------------------------------------------------- 292 293 struct DecrementLeaf 294 {}; 295 296 template<class T> 297 struct LeafFunctor<T, DecrementLeaf> 298 { 299 typedef int Type_t; 300 inline static Type_t apply(const T& cl, const DecrementLeaf&) 301 { 302 T& l = const_cast<T&>(cl); 303 --l; 304 return 0; 305 } 306 }; 307 308 #if defined(__MWERKS__) 309 // Workaround for screwy CWPro 4.1 bug. 310 template<class T> 311 struct LeafFunctor<const T*, DecrementLeaf> 312 { 313 typedef int Type_t; 314 inline static Type_t apply(const T*& const ci, const IncrementLeaf&) 315 { 316 T*& i = const_cast<T*&>(ci); 317 --i; 318 return 0; 319 } 320 }; 321 #endif 322 323 template<class T> 324 struct LeafFunctor<Scalar<T>, DecrementLeaf> 325 { 326 typedef int Type_t; 327 inline static Type_t apply(const Scalar<T>&, const DecrementLeaf&) { return 0; } 328 }; 329 330 //----------------------------------------------------------------------------- 331 // 332 // CLASS NAME 333 // DereferenceLeaf, LeafFunctor<{T, Scalar<T>}, DereferenceLeaf > 334 // 335 // DESCRIPTION 336 // A leaf-tag and functor used to dereference an iterator for scalars and 337 // leaves made up of STL iterators. 338 // 339 //----------------------------------------------------------------------------- 340 341 struct DereferenceLeaf 342 {}; 343 344 template<class ForwardIterator> 345 struct LeafFunctor<ForwardIterator, DereferenceLeaf> 346 { 347 typedef typename std::iterator_traits<ForwardIterator>::value_type Type_t; 348 inline static Type_t apply(const ForwardIterator& i, const DereferenceLeaf&) { return *i; } 349 }; 350 351 #if defined(__MWERKS__) 352 // Workaround for screwy CWPro 4.1 bug. 353 template<class T> 354 struct LeafFunctor<const T*, DereferenceLeaf> 355 { 356 typedef T Type_t; 357 inline static Type_t apply(const T* i, const DereferenceLeaf&) { return *i; } 358 }; 359 #endif 360 361 template<class T> 362 struct LeafFunctor<Scalar<T>, DereferenceLeaf> 363 { 364 typedef T Type_t; 365 inline static const Type_t& apply(const Scalar<T>& s, const DereferenceLeaf&) { return s.value(); } 366 }; 367 368 } // namespace qmcplusplus 369 370 #endif // PETE_PETE_FUNCTORS_H 371 372 // ACL:rcsinfo 373