00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __UT_ValArray_h__
00022 #define __UT_ValArray_h__
00023
00024 #include "UT_API.h"
00025 #include "UT_Algorithm.h"
00026 #include "UT_ArrayHelp.h"
00027 #include "UT_Assert.h"
00028 #include "UT_VectorTypes.h"
00029
00030 #include <SYS/SYS_TypeTraits.h>
00031 #include <SYS/SYS_Types.h>
00032
00033 #include <algorithm>
00034 #include <functional>
00035 #include <iostream>
00036 #include <limits>
00037 #include <vector>
00038 #include <stdio.h>
00039 #include <string.h>
00040
00041
00042 UT_API extern void UTsetCompareFloatsTolerance(float tol);
00043 UT_API extern float UTgetCompareFloatsTolerance();
00044 UT_API extern int UTcompareFloats(const float *a, const float *b);
00045 UT_API extern int UTcompareInts(const int *a, const int *b);
00046
00047
00048 template <typename T>
00049 class UT_Array
00050 {
00051 public:
00052 typedef T value_type;
00053
00054 typedef int (*Comparator)(const T *, const T *);
00055
00056 UT_Array(const UT_Array<T> &a);
00057 UT_Array(unsigned int sz, unsigned int count)
00058 {
00059 arr = (sz) ? (T *)calloc(sizeof(T), sz) : 0;
00060 if (sz < count) count = sz;
00061 nbrEntries = count;
00062 arrSize = sz;
00063 trivialConstructRange(arr, nbrEntries);
00064 }
00065 explicit UT_Array(unsigned int sz = 0) : arrSize(sz), nbrEntries(0)
00066 {
00067 arr = (sz) ? (T *)calloc(sizeof(T), sz) : 0;
00068 }
00069 ~UT_Array();
00070
00071 void swap(UT_Array<T> &other);
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 unsigned int append(void) { return insert(nbrEntries); }
00085 unsigned int append(const T &t);
00086 unsigned int append(const T &t, bool check_dup)
00087 {
00088 int idx;
00089 if (check_dup && ((idx = find(t)) != -1))
00090 return idx;
00091 return append(t);
00092 }
00093 void appendMultiple(const T &t, int count);
00094 unsigned int insert(unsigned index);
00095 unsigned int insert(const T &t, unsigned index);
00096
00097
00098
00099 unsigned int sortedInsert(const T &t, Comparator compare);
00100 template <typename ComparatorBool>
00101 unsigned int sortedInsert(const T &t, ComparatorBool is_less);
00102
00103 unsigned int uniqueSortedInsert(const T &t, Comparator compare);
00104 template <typename ComparatorBool>
00105 unsigned int uniqueSortedInsert(const T &t, ComparatorBool is_less);
00106
00107
00108
00109
00110 int uniqueSortedFind(const T &item, Comparator compare) const;
00111 template <typename ComparatorBool>
00112 int uniqueSortedFind(const T &item, ComparatorBool is_less) const;
00113
00114
00115
00116
00117
00118
00119
00120 template <typename ComparatorBool>
00121 void merge(const UT_Array<T> &other, int direction,
00122 bool allow_dups, ComparatorBool is_less);
00123
00124 bool hasSortedSubset(const UT_Array<T> &other,
00125 Comparator compare) const;
00126
00127 void sortedUnion(const UT_Array<T> &other, Comparator compare);
00128 void sortedUnion(
00129 const UT_Array<T> &other,
00130 UT_Array<T> &result,
00131 Comparator compare) const;
00132 void sortedIntersection(
00133 const UT_Array<T> &other,
00134 Comparator compare);
00135 void sortedIntersection(
00136 const UT_Array<T> &other,
00137 UT_Array<T> &result,
00138 Comparator compare) const;
00139 void sortedSetDifference(
00140 const UT_Array<T> &other,
00141 Comparator compare);
00142 void sortedSetDifference(
00143 const UT_Array<T> &other,
00144 UT_Array<T> &result,
00145 Comparator compare) const;
00146
00147
00148 void fromStdVector(const std::vector<T> &vec);
00149 void toStdVector(std::vector<T> &vec) const;
00150
00151
00152
00153
00154 unsigned int heapPush(const T &t, Comparator compare);
00155 template <typename ComparatorBool>
00156 unsigned int heapPush(const T &t, ComparatorBool is_less);
00157
00158
00159
00160 T heapPop(Comparator compare);
00161 template <typename ComparatorBool>
00162 T heapPop(ComparatorBool is_greater);
00163
00164
00165
00166 const T & heapMax() const
00167 {
00168 UT_ASSERT_P(nbrEntries > 0);
00169 return arr[0];
00170 }
00171
00172
00173 unsigned int concat(const UT_Array<T> &a);
00174
00175
00176 unsigned int multipleInsert(unsigned int index, unsigned int count);
00177
00178
00179
00180 unsigned int insertAt(const T &t, unsigned int index);
00181
00182
00183
00184
00185
00186 int findAndRemove(const T &t);
00187 int removeIndex(unsigned int index)
00188 {
00189 return (index < nbrEntries) ? removeAt(index) : -1;
00190 }
00191 void removeLast()
00192 {
00193 if (nbrEntries) removeAt(nbrEntries-1);
00194 }
00195
00196
00197 void removeRange(unsigned int begin_i, unsigned int end_i);
00198
00199
00200
00201
00202 template <typename IsEqual>
00203 int removeIf(IsEqual is_equal);
00204
00205
00206 template <typename IsEqual>
00207 void collapseIf(IsEqual is_equal)
00208 {
00209 removeIf(is_equal);
00210 resize(entries());
00211 }
00212
00213
00214
00215
00216
00217 void move(int srcIdx, int destIdx, int howMany);
00218
00219
00220 void cycle(int howMany);
00221
00222
00223
00224 void constant(const T &v);
00225 void zero();
00226
00227
00228
00229
00230
00231 int find(const T &t, unsigned int s = 0) const;
00232 int find(const T &t, Comparator compare) const;
00233
00234
00235
00236
00237
00238 int findString(const char *str) const;
00239
00240 void reverse();
00241
00242
00243
00244 int index(const T &t) const { return &t - arr; }
00245 int safeIndex(const T &t) const
00246 {
00247 return (&t >= arr && &t < (arr + nbrEntries))
00248 ? &t - arr : -1;
00249 }
00250
00251
00252
00253
00254 void sort(Comparator compare);
00255
00256
00257 template <typename ComparatorBool>
00258 void stdsort(ComparatorBool is_less)
00259 {
00260 std::sort(arr, arr + nbrEntries, is_less);
00261 }
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 template<typename ComparatorBool>
00272 void stableSort(ComparatorBool is_less)
00273 {
00274
00275
00276 if (entries() < 2)
00277 return;
00278
00279 std::stable_sort(array(),
00280 array() + entries(),
00281 is_less);
00282 }
00283
00284
00285 void sortedRemoveDuplicates();
00286
00287
00288
00289
00290
00291 template <typename ComparatorBool>
00292 T selectNthLargest(int idx, ComparatorBool is_less);
00293
00294
00295
00296 void resize(unsigned int sz, unsigned short copyFlag=1);
00297 void resizeIfNeeded(uint sz, bool copyFlag=true)
00298 {
00299 if (sz > capacity())
00300 resize(sz, copyFlag);
00301 }
00302
00303
00304
00305 uint capacity() const { return arrSize; }
00306 int64 getMemoryUsage() const { return capacity()*sizeof(T); }
00307 uint entries() const { return nbrEntries; }
00308 bool isEmpty() const { return nbrEntries==0; }
00309
00310
00311 void entries(unsigned int ne)
00312 {
00313 resizeIfNeeded(ne);
00314 if (nbrEntries > ne)
00315 trivialDestructRange(arr + ne, nbrEntries - ne);
00316 else if (ne > nbrEntries)
00317 trivialConstructRange(
00318 arr + nbrEntries, ne - nbrEntries);
00319 nbrEntries = ne;
00320 }
00321
00322
00323 void truncate(unsigned int ne)
00324 {
00325 if (entries() > ne)
00326 entries(ne);
00327 }
00328
00329 void clear() { entries(0); }
00330
00331
00332
00333 UT_Array<T> & operator=(const UT_Array<T> &a);
00334
00335
00336
00337
00338
00339 UT_Array<T> & assignSubset(const UT_Array<T> &a);
00340
00341
00342
00343
00344
00345
00346 bool operator==(const UT_Array<T> &a) const;
00347 bool operator!=(const UT_Array<T> &a) const;
00348 int isEqual(const UT_Array<T> &a, Comparator compare) const;
00349
00350
00351
00352 T & operator()(unsigned int i)
00353 {
00354 UT_ASSERT_P(i < nbrEntries);
00355 return arr[i];
00356 }
00357 const T & operator()(unsigned int i) const
00358 {
00359 UT_ASSERT_P(i < nbrEntries);
00360 return arr[i];
00361 }
00362 T & operator[](unsigned int i)
00363 {
00364 if (i >= nbrEntries)
00365 entries(i+1);
00366 return arr[i];
00367 }
00368
00369
00370 T operator[](unsigned int i) const
00371 {
00372 return i < nbrEntries ? arr[i] : T();
00373 }
00374 T & last()
00375 {
00376 UT_ASSERT_P(nbrEntries);
00377 return arr[nbrEntries-1];
00378 }
00379 const T & last() const
00380 {
00381 UT_ASSERT_P(nbrEntries);
00382 return arr[nbrEntries-1];
00383 }
00384
00385
00386
00387
00388
00389 unsigned int apply(int (*applyFct)(T &t, void *d), void *d);
00390
00391 template <typename BinaryOp>
00392 T accumulate(T init_value, BinaryOp add) const;
00393
00394 const T * getRawArray() const { return arr; }
00395 T * array() { return arr; }
00396 T * getArray() const { return arr; }
00397 void setCapacity(unsigned int sz) { arrSize = sz; }
00398
00399
00400
00401 T * aliasArray(T *newdata)
00402 { T *data = arr; arr = newdata; return data; }
00403
00404 template <bool FORWARD>
00405 class iteratorT
00406 {
00407 public:
00408 iteratorT()
00409 : myArray(NULL)
00410 , myCurr(0)
00411 {}
00412 iteratorT(const iteratorT<FORWARD> &src)
00413 {
00414 *this = src;
00415 }
00416 ~iteratorT() {}
00417
00418 T &operator*() const
00419 { return const_cast<T&>((*myArray)(myCurr)); }
00420 T &item() const
00421 { return const_cast<T&>((*myArray)(myCurr)); }
00422
00423 uint index() const { return myCurr; }
00424
00425 int operator==(const iteratorT &cmp) const
00426 {
00427
00428 if (atEnd() && cmp.atEnd())
00429 return true;
00430 return ((!myArray && !cmp.myArray) ||
00431 ((myArray == cmp.myArray) &&
00432 (myCurr == cmp.myCurr)));
00433 }
00434 int operator!=(const iteratorT &cmp) const
00435 { return !(*this == cmp); }
00436
00437 iteratorT &operator=(const iteratorT &src)
00438 {
00439 myArray = src.myArray;
00440 myCurr = src.myCurr;
00441 return *this;
00442 }
00443
00444
00445 iteratorT &operator++()
00446 {
00447 advance();
00448 return *this;
00449 }
00450
00451 iteratorT &operator++(int)
00452 {
00453 iteratorT tmp = *this;
00454 advance();
00455 return tmp;
00456 }
00457 bool atEnd() const
00458 {
00459 if (FORWARD)
00460 return !myArray || myCurr >= myArray->entries();
00461 else
00462 return !myArray || myCurr < 0;
00463 }
00464 void advance()
00465 {
00466 if (FORWARD)
00467 myCurr++;
00468 else
00469 myCurr--;
00470 }
00471 void rewind()
00472 {
00473 if (FORWARD)
00474 myCurr = 0;
00475 else
00476 myCurr = myArray ? (exint)myArray->entries() - 1 : -1;
00477 }
00478 private:
00479 iteratorT(const UT_Array<T> &array)
00480 : myArray(&array)
00481 , myCurr(0)
00482 {
00483 rewind();
00484 }
00485
00486 const UT_Array<T> *myArray;
00487 exint myCurr;
00488 friend class UT_Array<T>;
00489 };
00490 typedef iteratorT<true> const_iterator;
00491 typedef iteratorT<false> reverse_iterator;
00492 typedef const_iterator traverser;
00493
00494
00495
00496 const_iterator begin() const
00497 {
00498 if (arr && nbrEntries)
00499 return const_iterator(*this);
00500 return const_iterator();
00501 }
00502
00503 const_iterator end() const
00504 {
00505 return const_iterator();
00506 }
00507
00508
00509 reverse_iterator rbegin() const
00510 {
00511 if (arr && nbrEntries)
00512 return reverse_iterator(*this);
00513 return reverse_iterator();
00514 }
00515
00516 reverse_iterator rend() const
00517 {
00518 return reverse_iterator();
00519 }
00520
00521
00522 void removeItem(reverse_iterator &it)
00523 {
00524 removeAt(it.index());
00525 }
00526
00527
00528
00529
00530
00531 void unsafeShareData(UT_Array<T> &src)
00532 {
00533 arr = src.arr;
00534 arrSize = src.arrSize;
00535 nbrEntries = src.nbrEntries;
00536 }
00537 void unsafeClearData()
00538 {
00539 arr = 0;
00540 arrSize = 0;
00541 nbrEntries = 0;
00542 }
00543 protected:
00544
00545
00546
00547
00548 static bool isPOD()
00549 {
00550 return SYSisPOD<T>();
00551 }
00552
00553
00554 static void copyConstruct(T &dst, const T &src)
00555 {
00556 if (isPOD())
00557 dst = src;
00558 else
00559 new (&dst) T(src);
00560 }
00561 static void copyConstructRange(T *dst, const T *src, int n)
00562 {
00563 if (isPOD())
00564 memcpy(dst, src, n * sizeof(T));
00565 else
00566 {
00567 for (int i = 0; i < n; i++)
00568 new (&dst[i]) T(src[i]);
00569 }
00570 }
00571
00572
00573 static void trivialConstruct(T &dst)
00574 {
00575 if (!isPOD())
00576 new (&dst) T();
00577 }
00578 static void trivialConstructRange(T *dst, int n)
00579 {
00580 if (!isPOD())
00581 {
00582 for (int i = 0; i < n; i++)
00583 new (&dst[i]) T();
00584 }
00585 }
00586
00587
00588 static void trivialDestruct(T &dst)
00589 {
00590 if (!isPOD())
00591 dst.~T();
00592 }
00593 static void trivialDestructRange(T *dst, int n)
00594 {
00595 if (!isPOD())
00596 {
00597 for (int i = 0; i < n; i++)
00598 dst[i].~T();
00599 }
00600 }
00601
00602 private:
00603
00604 T * arr;
00605
00606
00607
00608 unsigned int arrSize;
00609 unsigned int nbrEntries;
00610
00611
00612 int removeAt(unsigned int index);
00613
00614 void heapify(unsigned int index, Comparator compare);
00615 template <typename ComparatorBool>
00616 void heapify(unsigned int index, ComparatorBool is_greater);
00617
00618 template<typename OS, typename S>
00619 friend OS &operator<<(OS &os, const UT_Array<S> &d);
00620 };
00621
00622 template <typename T>
00623 class UT_ValArray : public UT_Array<T>
00624 {
00625 public:
00626 typedef int (*Comparator)(const T *, const T *);
00627
00628
00629 explicit UT_ValArray(unsigned int sz = 0)
00630 : UT_Array<T>::UT_Array(sz)
00631 {}
00632 UT_ValArray(unsigned int sz, unsigned int count)
00633 : UT_Array<T>::UT_Array(sz, count)
00634 {}
00635
00636 static bool compareElementsBool(const T &a, const T &b)
00637 {
00638 return a < b;
00639 }
00640
00641
00642 void sortAndRemoveDuplicates()
00643 {
00644 stableSort(compareElementsBool);
00645 UT_Array<T>::sortedRemoveDuplicates();
00646 }
00647
00648 static int compareElements(const T *a, const T *b)
00649 {
00650 if (*a > *b)
00651 return 1;
00652 if (*a < *b)
00653 return -1;
00654 return 0;
00655 }
00656
00657 void sort(Comparator compare)
00658 {
00659 UT_Array<T>::sort(compare);
00660 }
00661 template <typename ComparatorBool>
00662 void stdsort(ComparatorBool is_less)
00663 {
00664 UT_Array<T>::stdsort(is_less);
00665 }
00666 void sort()
00667 {
00668 stdsort(std::less<T>());
00669 }
00670 void sortAscending()
00671 {
00672 sort();
00673 }
00674
00675 template<typename ComparatorBool>
00676 void stableSort(ComparatorBool is_less)
00677 {
00678 UT_Array<T>::stableSort(is_less);
00679 }
00680 void stableSort()
00681 {
00682 stableSort(std::less<T>());
00683 }
00684
00685 template <typename ComparatorBool>
00686 T selectNthLargest(int idx, ComparatorBool is_less)
00687 {
00688 return UT_Array<T>::selectNthLargest(idx, is_less);
00689 }
00690 T selectNthLargest(int idx)
00691 {
00692 return selectNthLargest(idx, std::less<T>());
00693 }
00694
00695 int uniqueSortedFind(const T &item, Comparator compare) const
00696 {
00697 return UT_Array<T>::uniqueSortedFind(item, compare);
00698 }
00699 template <typename ComparatorBool>
00700 int uniqueSortedFind(const T &item, ComparatorBool is_less) const
00701 {
00702 return UT_Array<T>::uniqueSortedFind(item, is_less);
00703 }
00704 int uniqueSortedFind(const T &item) const
00705 {
00706 return uniqueSortedFind(item, std::less<T>());
00707 }
00708 int uniqueSortedFindAscending(const T &item) const
00709 {
00710 return uniqueSortedFind(item);
00711 }
00712
00713 unsigned int sortedInsert(const T &t, Comparator compare)
00714 {
00715 return UT_Array<T>::sortedInsert(t, compare);
00716 }
00717 template <typename ComparatorBool>
00718 unsigned int sortedInsert(const T &t, ComparatorBool is_less)
00719 {
00720 return UT_Array<T>::sortedInsert(t, is_less);
00721 }
00722 unsigned int sortedInsert(const T &t)
00723 {
00724 return sortedInsert(t, std::less<T>());
00725 }
00726
00727 unsigned int uniqueSortedInsert(const T &t, Comparator compare)
00728 {
00729 return UT_Array<T>::uniqueSortedInsert(t, compare);
00730 }
00731 template <typename ComparatorBool>
00732 unsigned int uniqueSortedInsert(const T &t, ComparatorBool is_less)
00733 {
00734 return UT_Array<T>::uniqueSortedInsert(t, is_less);
00735 }
00736 unsigned int uniqueSortedInsert(const T &t)
00737 {
00738 return uniqueSortedInsert(t, std::less<T>());
00739 }
00740 unsigned int uniqueSortedInsertAscending(const T &t)
00741 {
00742 return uniqueSortedInsert(t);
00743 }
00744
00745 template <typename ComparatorBool>
00746 void merge(
00747 const UT_Array<T> &other,
00748 int direction,
00749 bool allow_dups,
00750 ComparatorBool is_less)
00751 {
00752 UT_Array<T>::merge(other, direction, allow_dups,
00753 is_less);
00754 }
00755 void merge(
00756 const UT_ValArray<T> &other,
00757 int direction,
00758 bool allow_dups)
00759 {
00760 merge(other, direction, allow_dups, std::less<T>());
00761 }
00762
00763 bool hasSortedSubset(
00764 const UT_ValArray<T> &other,
00765 Comparator compare = compareElements) const
00766 {
00767 return UT_Array<T>::hasSortedSubset(other, compare);
00768 }
00769 void sortedUnion(
00770 const UT_ValArray<T> &other,
00771 Comparator compare = compareElements)
00772 {
00773 UT_Array<T>::sortedUnion(other, compare);
00774 }
00775 void sortedUnion(
00776 const UT_ValArray<T> &other,
00777 UT_ValArray<T> &result,
00778 Comparator compare = compareElements) const
00779 {
00780 UT_Array<T>::sortedUnion(other, result, compare);
00781 }
00782 void sortedIntersection(
00783 const UT_ValArray<T> &other,
00784 Comparator compare = compareElements)
00785 {
00786 UT_Array<T>::sortedIntersection(other, compare);
00787 }
00788 void sortedIntersection(
00789 const UT_ValArray<T> &other,
00790 UT_ValArray<T> &result,
00791 Comparator compare = compareElements) const
00792 {
00793 UT_Array<T>::sortedIntersection(other, result, compare);
00794 }
00795 void sortedSetDifference(
00796 const UT_ValArray<T> &other,
00797 Comparator compare = compareElements)
00798 {
00799 UT_Array<T>::sortedSetDifference(other, compare);
00800 }
00801 void sortedSetDifference(
00802 const UT_ValArray<T> &other,
00803 UT_ValArray<T> &result,
00804 Comparator compare = compareElements) const
00805 {
00806 UT_Array<T>::sortedSetDifference(other, result, compare);
00807 }
00808
00809 unsigned int heapPush(const T &t, Comparator compare)
00810 {
00811 return UT_Array<T>::heapPush(t, compare);
00812 }
00813 template <typename ComparatorBool>
00814 unsigned int heapPush(const T &t, ComparatorBool is_less)
00815 {
00816 return UT_Array<T>::heapPush(t, is_less);
00817 }
00818 unsigned int heapPush(const T &t)
00819 {
00820 return heapPush(t, std::less<T>());
00821 }
00822 T heapPop(Comparator compare)
00823 {
00824 return UT_Array<T>::heapPop(compare);
00825 }
00826 template <typename ComparatorBool>
00827 T heapPop(ComparatorBool is_greater)
00828 {
00829 return UT_Array<T>::heapPop(is_greater);
00830 }
00831 T heapPop()
00832 {
00833 return heapPop(std::greater<T>());
00834 }
00835
00836 static bool isElementZero(const T &a)
00837 {
00838 return !a;
00839 }
00840
00841 int removeZeros()
00842 {
00843 return this->removeIf(isElementZero);
00844 }
00845
00846
00847 void collapse()
00848 {
00849 this->collapseIf(isElementZero);
00850 }
00851
00852
00853
00854
00855 T sum() const
00856 {
00857 UT_ASSERT(!"Invalid function");
00858 return T();
00859 }
00860
00861 void display() const
00862 {
00863 printf("%d entries, contents not displayable.\n",
00864 UT_Array<T>::entries());
00865 }
00866
00867
00868 private:
00869
00870 };
00871
00872
00873 template <typename T, typename S>
00874 void
00875 UTconvertArray(UT_Array<T> &dest, const UT_Array<S> &src)
00876 {
00877 int n = src.entries();
00878 dest.resize(n);
00879 dest.entries(n);
00880 for (int i = 0; i < n; i++)
00881 dest(i) = T(src(i));
00882 }
00883 template <typename T, typename S>
00884 void
00885 UTconvertArray(UT_Array<T> &dest, const S *src, int n)
00886 {
00887 dest.resize(n);
00888 dest.entries(n);
00889 for (int i = 0; i < n; i++)
00890 dest(i) = T(src[i]);
00891 }
00892 template <typename T, typename S>
00893 void
00894 UTconvertArray(T *dest, const UT_Array<S> &src)
00895 {
00896
00897 int n = src.entries();
00898 for (int i = 0; i < n; i++)
00899 dest[i] = T(src(i));
00900 }
00901 template <typename T, typename S>
00902 void
00903 UTconvertArray(T *dest, const S *src, int64 n)
00904 {
00905
00906 for (int64 i = 0; i < n; i++)
00907 dest[i] = T(src[i]);
00908 }
00909
00910 #if defined( WIN32 ) || defined( LINUX ) || defined(MBSD) || defined(GAMEOS)
00911 #include "UT_ValArrayImpl.h"
00912 #endif
00913
00914 UT_SWAPPER_TEMPLATE( UT_Array );
00915
00916 template <>
00917 inline int
00918 UT_ValArray<fpreal32>::compareElements(const fpreal32 *a, const fpreal32 *b)
00919 {
00920 const float tol = UTgetCompareFloatsTolerance();
00921 if( *a>*b+tol )
00922 return 1;
00923 if( *a<*b-tol )
00924 return -1;
00925 return 0;
00926 }
00927
00928 template <>
00929 inline int
00930 UT_ValArray<fpreal64>::compareElements(const fpreal64 *a, const fpreal64 *b)
00931 {
00932 const float tol = UTgetCompareFloatsTolerance();
00933 if( *a>*b+tol )
00934 return 1;
00935 if( *a<*b-tol )
00936 return -1;
00937 return 0;
00938 }
00939
00940 #define UT_DECL_ARITHMETIC_SPECIALIZATION(T) \
00941 template <> UT_API T UT_ValArray<T>::sum() const; \
00942 template <> UT_API void UT_ValArray<T>::display() const; \
00943
00944 UT_DECL_ARITHMETIC_SPECIALIZATION(int32)
00945 UT_DECL_ARITHMETIC_SPECIALIZATION(int64)
00946 UT_DECL_ARITHMETIC_SPECIALIZATION(fpreal32)
00947 UT_DECL_ARITHMETIC_SPECIALIZATION(fpreal64)
00948 #undef UT_DECL_ARITHMETIC_SPECIALIZATION
00949
00950 template <>
00951 UT_API void UT_Array<fpreal32>::constant(const fpreal32 &val);
00952
00953
00954
00955 template<typename T>
00956 class UT_API UT_ArrayPrintLimit
00957 {
00958 public:
00959 UT_ArrayPrintLimit(const UT_Array<T> &a, uint limit = 100) :
00960 myA(a), myLimit(limit) {}
00961 private:
00962 const UT_Array<T> &myA;
00963 uint myLimit;
00964
00965 template<typename OS, typename S>
00966 friend OS &operator<<(OS &os, const UT_ArrayPrintLimit<S> &d);
00967 };
00968
00969 template<typename OS, typename S>
00970 inline OS &
00971 operator<<(OS &os, const UT_ArrayPrintLimit<S> &d)
00972 {
00973 uint idx;
00974
00975 os << "[" << d.myA.entries() << "]={";
00976 for (idx = 0; idx < d.myA.entries(); idx++)
00977 {
00978 if (idx > 0) os << ", ";
00979 if (idx > d.myLimit)
00980 {
00981 cerr << "...";
00982 break;
00983 }
00984 os << d.myA(idx);
00985 }
00986 os << "}";
00987 return os;
00988 }
00989
00990 template<typename OS, typename S>
00991 inline OS &
00992 operator<<(OS &os, const UT_Array<S> &d)
00993 {
00994 os << UT_ArrayPrintLimit<S>(d);
00995 return os;
00996 }
00997
00998 #endif