summaryrefslogtreecommitdiff
path: root/thirdparty/linux/include/coin1/CoinSort.hpp
diff options
context:
space:
mode:
authorGeorgey2017-07-05 11:40:43 +0530
committerGeorgey2017-07-05 11:40:43 +0530
commit938fef4a37a7b7c61b4b6ff74cb4cfd2f100c427 (patch)
treeb343c0ee5609433c80e0de1db8b6886c9126dc2d /thirdparty/linux/include/coin1/CoinSort.hpp
parent5b72577efe080c5294b32d804e4d26351fef30bc (diff)
downloadFOSSEE-Optimization-toolbox-938fef4a37a7b7c61b4b6ff74cb4cfd2f100c427.tar.gz
FOSSEE-Optimization-toolbox-938fef4a37a7b7c61b4b6ff74cb4cfd2f100c427.tar.bz2
FOSSEE-Optimization-toolbox-938fef4a37a7b7c61b4b6ff74cb4cfd2f100c427.zip
Added linux shared libraries and header files for int and ecos functions
Diffstat (limited to 'thirdparty/linux/include/coin1/CoinSort.hpp')
-rw-r--r--thirdparty/linux/include/coin1/CoinSort.hpp678
1 files changed, 678 insertions, 0 deletions
diff --git a/thirdparty/linux/include/coin1/CoinSort.hpp b/thirdparty/linux/include/coin1/CoinSort.hpp
new file mode 100644
index 0000000..259fb35
--- /dev/null
+++ b/thirdparty/linux/include/coin1/CoinSort.hpp
@@ -0,0 +1,678 @@
+/* $Id: CoinSort.hpp 1594 2013-04-19 14:33:00Z forrest $ */
+// Copyright (C) 2000, International Business Machines
+// Corporation and others. All Rights Reserved.
+// This code is licensed under the terms of the Eclipse Public License (EPL).
+
+#ifndef CoinSort_H
+#define CoinSort_H
+
+#include <functional>
+#include <new>
+#include <algorithm>
+#include "CoinDistance.hpp"
+
+// Uncomment the next three lines to get thorough initialisation of memory.
+// #ifndef ZEROFAULT
+// #define ZEROFAULT
+// #endif
+
+#ifdef COIN_FAST_CODE
+#ifndef COIN_USE_EKK_SORT
+#define COIN_USE_EKK_SORT
+#endif
+#endif
+
+//#############################################################################
+
+/** An ordered pair. It's the same as std::pair, just this way it'll have the
+ same look as the triple sorting. */
+template <class S, class T>
+struct CoinPair {
+public:
+ /// First member of pair
+ S first;
+ /// Second member of pair
+ T second;
+public:
+ /// Construct from ordered pair
+ CoinPair(const S& s, const T& t) : first(s), second(t) {}
+};
+
+//#############################################################################
+
+/**@name Comparisons on first element of two ordered pairs */
+//@{
+/** Function operator.
+ Returns true if t1.first &lt; t2.first (i.e., increasing). */
+template < class S, class T>
+class CoinFirstLess_2 {
+public:
+ /// Compare function
+ inline bool operator()(const CoinPair<S,T>& t1,
+ const CoinPair<S,T>& t2) const
+ { return t1.first < t2.first; }
+};
+//-----------------------------------------------------------------------------
+/** Function operator.
+ Returns true if t1.first &gt; t2.first (i.e, decreasing). */
+template < class S, class T>
+class CoinFirstGreater_2 {
+public:
+ /// Compare function
+ inline bool operator()(const CoinPair<S,T>& t1,
+ const CoinPair<S,T>& t2) const
+ { return t1.first > t2.first; }
+};
+//-----------------------------------------------------------------------------
+/** Function operator.
+ Returns true if abs(t1.first) &lt; abs(t2.first) (i.e., increasing). */
+template < class S, class T>
+class CoinFirstAbsLess_2 {
+public:
+ /// Compare function
+ inline bool operator()(const CoinPair<S,T>& t1,
+ const CoinPair<S,T>& t2) const
+ {
+ const T t1Abs = t1.first < static_cast<T>(0) ? -t1.first : t1.first;
+ const T t2Abs = t2.first < static_cast<T>(0) ? -t2.first : t2.first;
+ return t1Abs < t2Abs;
+ }
+};
+//-----------------------------------------------------------------------------
+/** Function operator.
+ Returns true if abs(t1.first) &gt; abs(t2.first) (i.e., decreasing). */
+template < class S, class T>
+class CoinFirstAbsGreater_2 {
+public:
+ /// Compare function
+ inline bool operator()(CoinPair<S,T> t1, CoinPair<S,T> t2) const
+ {
+ const T t1Abs = t1.first < static_cast<T>(0) ? -t1.first : t1.first;
+ const T t2Abs = t2.first < static_cast<T>(0) ? -t2.first : t2.first;
+ return t1Abs > t2Abs;
+ }
+};
+//-----------------------------------------------------------------------------
+/** Function operator.
+ Compare based on the entries of an external vector, i.e., returns true if
+ vec[t1.first &lt; vec[t2.first] (i.e., increasing wrt. vec). Note that to
+ use this comparison operator .first must be a data type automatically
+ convertible to int. */
+template < class S, class T, class V>
+class CoinExternalVectorFirstLess_2 {
+private:
+ CoinExternalVectorFirstLess_2();
+private:
+ const V* vec_;
+public:
+ inline bool operator()(const CoinPair<S,T>& t1,
+ const CoinPair<S,T>& t2) const
+ { return vec_[t1.first] < vec_[t2.first]; }
+ CoinExternalVectorFirstLess_2(const V* v) : vec_(v) {}
+};
+//-----------------------------------------------------------------------------
+/** Function operator.
+ Compare based on the entries of an external vector, i.e., returns true if
+ vec[t1.first &gt; vec[t2.first] (i.e., decreasing wrt. vec). Note that to
+ use this comparison operator .first must be a data type automatically
+ convertible to int. */
+template < class S, class T, class V>
+class CoinExternalVectorFirstGreater_2 {
+private:
+ CoinExternalVectorFirstGreater_2();
+private:
+ const V* vec_;
+public:
+ inline bool operator()(const CoinPair<S,T>& t1,
+ const CoinPair<S,T>& t2) const
+ { return vec_[t1.first] > vec_[t2.first]; }
+ CoinExternalVectorFirstGreater_2(const V* v) : vec_(v) {}
+};
+//@}
+
+//#############################################################################
+
+/** Sort a pair of containers.<br>
+
+ Iter_S - iterator for first container<br>
+ Iter_T - iterator for 2nd container<br>
+ CoinCompare2 - class comparing CoinPairs<br>
+*/
+
+#ifdef COIN_SORT_ARBITRARY_CONTAINERS
+template <class Iter_S, class Iter_T, class CoinCompare2> void
+CoinSort_2(Iter_S sfirst, Iter_S slast, Iter_T tfirst, const CoinCompare2& pc)
+{
+ typedef typename std::iterator_traits<Iter_S>::value_type S;
+ typedef typename std::iterator_traits<Iter_T>::value_type T;
+ const size_t len = coinDistance(sfirst, slast);
+ if (len <= 1)
+ return;
+
+ typedef CoinPair<S,T> ST_pair;
+ ST_pair* x = static_cast<ST_pair*>(::operator new(len * sizeof(ST_pair)));
+# ifdef ZEROFAULT
+ memset(x,0,(len*sizeof(ST_pair))) ;
+# endif
+
+ int i = 0;
+ Iter_S scurrent = sfirst;
+ Iter_T tcurrent = tfirst;
+ while (scurrent != slast) {
+ new (x+i++) ST_pair(*scurrent++, *tcurrent++);
+ }
+
+ std::sort(x.begin(), x.end(), pc);
+
+ scurrent = sfirst;
+ tcurrent = tfirst;
+ for (i = 0; i < len; ++i) {
+ *scurrent++ = x[i].first;
+ *tcurrent++ = x[i].second;
+ }
+
+ ::operator delete(x);
+}
+//-----------------------------------------------------------------------------
+template <class Iter_S, class Iter_T> void
+CoinSort_2(Iter_S sfirst, Iter_S slast, Iter_T tfirst)
+{
+ typedef typename std::iterator_traits<Iter_S>::value_type S;
+ typedef typename std::iterator_traits<Iter_T>::value_type T;
+ CoinSort_2(sfirst, slast, tfirst, CoinFirstLess_2<S,T>());
+}
+
+#else //=======================================================================
+
+template <class S, class T, class CoinCompare2> void
+CoinSort_2(S* sfirst, S* slast, T* tfirst, const CoinCompare2& pc)
+{
+ const size_t len = coinDistance(sfirst, slast);
+ if (len <= 1)
+ return;
+
+ typedef CoinPair<S,T> ST_pair;
+ ST_pair* x = static_cast<ST_pair*>(::operator new(len * sizeof(ST_pair)));
+# ifdef ZEROFAULT
+ // Can show RUI errors on some systems due to copy of ST_pair with gaps.
+ // E.g., <int, double> has 4 byte alignment gap on Solaris/SUNWspro.
+ memset(x,0,(len*sizeof(ST_pair))) ;
+# endif
+
+ size_t i = 0;
+ S* scurrent = sfirst;
+ T* tcurrent = tfirst;
+ while (scurrent != slast) {
+ new (x+i++) ST_pair(*scurrent++, *tcurrent++);
+ }
+
+ std::sort(x, x + len, pc);
+
+ scurrent = sfirst;
+ tcurrent = tfirst;
+ for (i = 0; i < len; ++i) {
+ *scurrent++ = x[i].first;
+ *tcurrent++ = x[i].second;
+ }
+
+ ::operator delete(x);
+}
+template <class S, class T> void
+// This Always uses std::sort
+CoinSort_2Std(S* sfirst, S* slast, T* tfirst)
+{
+ CoinSort_2(sfirst, slast, tfirst, CoinFirstLess_2<S,T>());
+}
+#ifndef COIN_USE_EKK_SORT
+//-----------------------------------------------------------------------------
+template <class S, class T> void
+CoinSort_2(S* sfirst, S* slast, T* tfirst)
+{
+ CoinSort_2(sfirst, slast, tfirst, CoinFirstLess_2<S,T>());
+}
+#else
+//-----------------------------------------------------------------------------
+extern int boundary_sort;
+extern int boundary_sort2;
+extern int boundary_sort3;
+/// Sort without new and delete
+template <class S, class T> void
+CoinSort_2(S* key, S* lastKey, T* array2)
+{
+ const size_t number = coinDistance(key, lastKey);
+ if (number <= 1) {
+ return;
+ } else if (number>10000) {
+ CoinSort_2Std(key, lastKey, array2);
+ return;
+ }
+#if 0
+ if (number==boundary_sort3) {
+ printf("before sort %d entries\n",number);
+ for (int j=0;j<number;j++) {
+ std::cout<<" ( "<<key[j]<<","<<array2[j]<<")";
+ }
+ std::cout<<std::endl;
+ }
+#endif
+ int minsize=10;
+ int n = static_cast<int>(number);
+ int sp;
+ S *v = key;
+ S *m, t;
+ S * ls[32] , * rs[32];
+ S *l , *r , c;
+ T it;
+ int j;
+ /*check already sorted */
+ S last=key[0];
+ for (j=1;j<n;j++) {
+ if (key[j]>=last) {
+ last=key[j];
+ } else {
+ break;
+ } /* endif */
+ } /* endfor */
+ if (j==n) {
+ return;
+ } /* endif */
+ sp = 0 ; ls[sp] = v ; rs[sp] = v + (n-1) ;
+ while( sp >= 0 )
+ {
+ if ( rs[sp] - ls[sp] > minsize )
+ {
+ l = ls[sp] ; r = rs[sp] ; m = l + (r-l)/2 ;
+ if ( *l > *m )
+ {
+ t = *l ; *l = *m ; *m = t ;
+ it = array2[l-v] ; array2[l-v] = array2[m-v] ; array2[m-v] = it ;
+ }
+ if ( *m > *r )
+ {
+ t = *m ; *m = *r ; *r = t ;
+ it = array2[m-v] ; array2[m-v] = array2[r-v] ; array2[r-v] = it ;
+ if ( *l > *m )
+ {
+ t = *l ; *l = *m ; *m = t ;
+ it = array2[l-v] ; array2[l-v] = array2[m-v] ; array2[m-v] = it ;
+ }
+ }
+ c = *m ;
+ while ( r - l > 1 )
+ {
+ while ( *(++l) < c ) ;
+ while ( *(--r) > c ) ;
+ t = *l ; *l = *r ; *r = t ;
+ it = array2[l-v] ; array2[l-v] = array2[r-v] ; array2[r-v] = it ;
+ }
+ l = r - 1 ;
+ if ( l < m )
+ { ls[sp+1] = ls[sp] ;
+ rs[sp+1] = l ;
+ ls[sp ] = r ;
+ }
+ else
+ { ls[sp+1] = r ;
+ rs[sp+1] = rs[sp] ;
+ rs[sp ] = l ;
+ }
+ sp++ ;
+ }
+ else sp-- ;
+ }
+ for ( l = v , m = v + (n-1) ; l < m ; l++ )
+ { if ( *l > *(l+1) )
+ {
+ c = *(l+1) ;
+ it = array2[(l-v)+1] ;
+ for ( r = l ; r >= v && *r > c ; r-- )
+ {
+ *(r+1) = *r ;
+ array2[(r-v)+1] = array2[(r-v)] ;
+ }
+ *(r+1) = c ;
+ array2[(r-v)+1] = it ;
+ }
+ }
+#if 0
+ if (number==boundary_sort3) {
+ printf("after sort %d entries\n",number);
+ for (int j=0;j<number;j++) {
+ std::cout<<" ( "<<key[j]<<","<<array2[j]<<")";
+ }
+ std::cout<<std::endl;
+ CoinSort_2Many(key, lastKey, array2);
+ printf("after2 sort %d entries\n",number);
+ for (int j=0;j<number;j++) {
+ std::cout<<" ( "<<key[j]<<","<<array2[j]<<")";
+ }
+ std::cout<<std::endl;
+ }
+#endif
+}
+#endif
+#endif
+/// Sort without new and delete
+template <class S, class T> void
+CoinShortSort_2(S* key, S* lastKey, T* array2)
+{
+ const size_t number = coinDistance(key, lastKey);
+ if (number <= 2) {
+ if (number == 2 && key[0] > key[1]) {
+ S tempS = key[0];
+ T tempT = array2[0];
+ key[0] = key[1];
+ array2[0] = array2[1];
+ key[1] = tempS;
+ array2[1] = tempT;
+ }
+ return;
+ } else if (number>10000) {
+ CoinSort_2Std(key, lastKey, array2);
+ return;
+ }
+ int minsize=10;
+ size_t n = number;
+ int sp;
+ S *v = key;
+ S *m, t;
+ S * ls[32] , * rs[32];
+ S *l , *r , c;
+ T it;
+ size_t j;
+ /*check already sorted */
+ S last=key[0];
+ for (j=1;j<n;j++) {
+ if (key[j]>=last) {
+ last=key[j];
+ } else {
+ break;
+ } /* endif */
+ } /* endfor */
+ if (j==n) {
+ return;
+ } /* endif */
+ sp = 0 ; ls[sp] = v ; rs[sp] = v + (n-1) ;
+ while( sp >= 0 )
+ {
+ if ( rs[sp] - ls[sp] > minsize )
+ {
+ l = ls[sp] ; r = rs[sp] ; m = l + (r-l)/2 ;
+ if ( *l > *m )
+ {
+ t = *l ; *l = *m ; *m = t ;
+ it = array2[l-v] ; array2[l-v] = array2[m-v] ; array2[m-v] = it ;
+ }
+ if ( *m > *r )
+ {
+ t = *m ; *m = *r ; *r = t ;
+ it = array2[m-v] ; array2[m-v] = array2[r-v] ; array2[r-v] = it ;
+ if ( *l > *m )
+ {
+ t = *l ; *l = *m ; *m = t ;
+ it = array2[l-v] ; array2[l-v] = array2[m-v] ; array2[m-v] = it ;
+ }
+ }
+ c = *m ;
+ while ( r - l > 1 )
+ {
+ while ( *(++l) < c ) ;
+ while ( *(--r) > c ) ;
+ t = *l ; *l = *r ; *r = t ;
+ it = array2[l-v] ; array2[l-v] = array2[r-v] ; array2[r-v] = it ;
+ }
+ l = r - 1 ;
+ if ( l < m )
+ { ls[sp+1] = ls[sp] ;
+ rs[sp+1] = l ;
+ ls[sp ] = r ;
+ }
+ else
+ { ls[sp+1] = r ;
+ rs[sp+1] = rs[sp] ;
+ rs[sp ] = l ;
+ }
+ sp++ ;
+ }
+ else sp-- ;
+ }
+ for ( l = v , m = v + (n-1) ; l < m ; l++ )
+ { if ( *l > *(l+1) )
+ {
+ c = *(l+1) ;
+ it = array2[(l-v)+1] ;
+ for ( r = l ; r >= v && *r > c ; r-- )
+ {
+ *(r+1) = *r ;
+ array2[(r-v)+1] = array2[(r-v)] ;
+ }
+ *(r+1) = c ;
+ array2[(r-v)+1] = it ;
+ }
+ }
+}
+//#############################################################################
+//#############################################################################
+
+/**@name Ordered Triple Struct */
+template <class S, class T, class U>
+class CoinTriple {
+public:
+ /// First member of triple
+ S first;
+ /// Second member of triple
+ T second;
+ /// Third member of triple
+ U third;
+public:
+ /// Construct from ordered triple
+ CoinTriple(const S& s, const T& t, const U& u):first(s),second(t),third(u) {}
+};
+
+//#############################################################################
+/**@name Comparisons on first element of two ordered triples */
+//@{
+/** Function operator.
+ Returns true if t1.first &lt; t2.first (i.e., increasing). */
+template < class S, class T, class U >
+class CoinFirstLess_3 {
+public:
+ /// Compare function
+ inline bool operator()(const CoinTriple<S,T,U>& t1,
+ const CoinTriple<S,T,U>& t2) const
+ { return t1.first < t2.first; }
+};
+//-----------------------------------------------------------------------------
+/** Function operator.
+ Returns true if t1.first &gt; t2.first (i.e, decreasing). */
+template < class S, class T, class U >
+class CoinFirstGreater_3 {
+public:
+ /// Compare function
+ inline bool operator()(const CoinTriple<S,T,U>& t1,
+ const CoinTriple<S,T,U>& t2) const
+ { return t1.first>t2.first; }
+};
+//-----------------------------------------------------------------------------
+/** Function operator.
+ Returns true if abs(t1.first) &lt; abs(t2.first) (i.e., increasing). */
+template < class S, class T, class U >
+class CoinFirstAbsLess_3 {
+public:
+ /// Compare function
+ inline bool operator()(const CoinTriple<S,T,U>& t1,
+ const CoinTriple<S,T,U>& t2) const
+ {
+ const T t1Abs = t1.first < static_cast<T>(0) ? -t1.first : t1.first;
+ const T t2Abs = t2.first < static_cast<T>(0) ? -t2.first : t2.first;
+ return t1Abs < t2Abs;
+ }
+};
+//-----------------------------------------------------------------------------
+/** Function operator.
+ Returns true if abs(t1.first) &gt; abs(t2.first) (i.e., decreasing). */
+template < class S, class T, class U >
+class CoinFirstAbsGreater_3 {
+public:
+ /// Compare function
+ inline bool operator()(const CoinTriple<S,T,U>& t1,
+ const CoinTriple<S,T,U>& t2) const
+ {
+ const T t1Abs = t1.first < static_cast<T>(0) ? -t1.first : t1.first;
+ const T t2Abs = t2.first < static_cast<T>(0) ? -t2.first : t2.first;
+ return t1Abs > t2Abs;
+ }
+};
+//-----------------------------------------------------------------------------
+/** Function operator.
+ Compare based on the entries of an external vector, i.e., returns true if
+ vec[t1.first &lt; vec[t2.first] (i.e., increasing wrt. vec). Note that to
+ use this comparison operator .first must be a data type automatically
+ convertible to int. */
+template < class S, class T, class U, class V>
+class CoinExternalVectorFirstLess_3 {
+private:
+ CoinExternalVectorFirstLess_3();
+private:
+ const V* vec_;
+public:
+ inline bool operator()(const CoinTriple<S,T,U>& t1,
+ const CoinTriple<S,T,U>& t2) const
+ { return vec_[t1.first] < vec_[t2.first]; }
+ CoinExternalVectorFirstLess_3(const V* v) : vec_(v) {}
+};
+//-----------------------------------------------------------------------------
+/** Function operator.
+ Compare based on the entries of an external vector, i.e., returns true if
+ vec[t1.first &gt; vec[t2.first] (i.e., decreasing wrt. vec). Note that to
+ use this comparison operator .first must be a data type automatically
+ convertible to int. */
+template < class S, class T, class U, class V>
+class CoinExternalVectorFirstGreater_3 {
+private:
+ CoinExternalVectorFirstGreater_3();
+private:
+ const V* vec_;
+public:
+ inline bool operator()(const CoinTriple<S,T,U>& t1,
+ const CoinTriple<S,T,U>& t2) const
+ { return vec_[t1.first] > vec_[t2.first]; }
+ CoinExternalVectorFirstGreater_3(const V* v) : vec_(v) {}
+};
+//@}
+
+//#############################################################################
+
+/**@name Typedefs for sorting the entries of a packed vector based on an
+ external vector. */
+//@{
+/// Sort packed vector in increasing order of the external vector
+typedef CoinExternalVectorFirstLess_3<int, int, double, double>
+CoinIncrSolutionOrdered;
+/// Sort packed vector in decreasing order of the external vector
+typedef CoinExternalVectorFirstGreater_3<int, int, double, double>
+CoinDecrSolutionOrdered;
+//@}
+
+//#############################################################################
+
+/** Sort a triple of containers.<br>
+
+ Iter_S - iterator for first container<br>
+ Iter_T - iterator for 2nd container<br>
+ Iter_U - iterator for 3rd container<br>
+ CoinCompare3 - class comparing CoinTriples<br>
+*/
+#ifdef COIN_SORT_ARBITRARY_CONTAINERS
+template <class Iter_S, class Iter_T, class Iter_U, class CoinCompare3> void
+CoinSort_3(Iter_S sfirst, Iter_S slast, Iter_T tfirst, Iter_U, ufirst,
+ const CoinCompare3& tc)
+{
+ typedef typename std::iterator_traits<Iter_S>::value_type S;
+ typedef typename std::iterator_traits<Iter_T>::value_type T;
+ typedef typename std::iterator_traits<Iter_U>::value_type U;
+ const size_t len = coinDistance(sfirst, slast);
+ if (len <= 1)
+ return;
+
+ typedef CoinTriple<S,T,U> STU_triple;
+ STU_triple* x =
+ static_cast<STU_triple*>(::operator new(len * sizeof(STU_triple)));
+
+ int i = 0;
+ Iter_S scurrent = sfirst;
+ Iter_T tcurrent = tfirst;
+ Iter_U ucurrent = ufirst;
+ while (scurrent != slast) {
+ new (x+i++) STU_triple(*scurrent++, *tcurrent++, *ucurrent++);
+ }
+
+ std::sort(x, x+len, tc);
+
+ scurrent = sfirst;
+ tcurrent = tfirst;
+ ucurrent = ufirst;
+ for (i = 0; i < len; ++i) {
+ *scurrent++ = x[i].first;
+ *tcurrent++ = x[i].second;
+ *ucurrent++ = x[i].third;
+ }
+
+ ::operator delete(x);
+}
+//-----------------------------------------------------------------------------
+template <class Iter_S, class Iter_T, class Iter_U> void
+CoinSort_3(Iter_S sfirst, Iter_S slast, Iter_T tfirst, Iter_U, ufirst)
+{
+ typedef typename std::iterator_traits<Iter_S>::value_type S;
+ typedef typename std::iterator_traits<Iter_T>::value_type T;
+ typedef typename std::iterator_traits<Iter_U>::value_type U;
+ CoinSort_3(sfirts, slast, tfirst, ufirst, CoinFirstLess_3<S,T,U>());
+}
+
+#else //=======================================================================
+
+template <class S, class T, class U, class CoinCompare3> void
+CoinSort_3(S* sfirst, S* slast, T* tfirst, U* ufirst, const CoinCompare3& tc)
+{
+ const size_t len = coinDistance(sfirst,slast);
+ if (len <= 1)
+ return;
+
+ typedef CoinTriple<S,T,U> STU_triple;
+ STU_triple* x =
+ static_cast<STU_triple*>(::operator new(len * sizeof(STU_triple)));
+
+ size_t i = 0;
+ S* scurrent = sfirst;
+ T* tcurrent = tfirst;
+ U* ucurrent = ufirst;
+ while (scurrent != slast) {
+ new (x+i++) STU_triple(*scurrent++, *tcurrent++, *ucurrent++);
+ }
+
+ std::sort(x, x+len, tc);
+
+ scurrent = sfirst;
+ tcurrent = tfirst;
+ ucurrent = ufirst;
+ for (i = 0; i < len; ++i) {
+ *scurrent++ = x[i].first;
+ *tcurrent++ = x[i].second;
+ *ucurrent++ = x[i].third;
+ }
+
+ ::operator delete(x);
+}
+//-----------------------------------------------------------------------------
+template <class S, class T, class U> void
+CoinSort_3(S* sfirst, S* slast, T* tfirst, U* ufirst)
+{
+ CoinSort_3(sfirst, slast, tfirst, ufirst, CoinFirstLess_3<S,T,U>());
+}
+
+#endif
+
+//#############################################################################
+
+#endif