/**
*
* @file FunctorSort.cpp
*
* @authors M. Laporte, D. Mathieu
*
* @date 07/12/2011
*
* @version V1.0
*
**/
#include <string>
#include <vector>
#include <algorithm> // sort()
#include <iostream>
#include <utility> // swap()
using namespace std;
namespace
{
template <typename T>
class ILessThanGen
{
public :
virtual ~ILessThanGen (void) {}
virtual bool operator () (const T &, const T &) const noexcept = 0;
}; // ILessThanGen
template <typename iter_t, typename LessThan>
iter_t partitionnement (const iter_t & first, const iter_t & last,
const LessThan & compar)
{
bool isUp (true);
iter_t pivot (first);
iter_t courant (last);
int incr (-1);
while (pivot != courant)
{
if (((!isUp) && compar (*pivot, *courant)) ||
(isUp && compar (*courant, *pivot)))
{
swap (*pivot, *courant);
swap (pivot, courant);
isUp = ! isUp;
incr = -incr;
}
courant = courant + incr;
}
return pivot;
} // partitionnement()
template <typename iter_t, typename LessThan>
void quickSort (const iter_t & beg, const iter_t & end,
const LessThan & compar)
{
if (beg < end)
{
iter_t pos = partitionnement (beg, end - 1, compar);
quickSort (beg, pos, compar);
quickSort (pos + 1, end, compar);
}
} // quickSort ()
class Pers
{
string myNom;
unsigned myAge;
public :
Pers (const string & Nom, unsigned Age)
: myNom (Nom), myAge (Age) {}
const string & getNom (void) const noexcept { return myNom; }
unsigned getAge (void) const noexcept { return myAge; }
private :
ostream & display (ostream & os) const
{
return os << getAge () << " - " << getNom ();
} // display()
public :
friend ostream & operator << (ostream & os, const Pers & p)
{
return p.display (os);
}
}; // Pers
class TriParAgeAsc : public ILessThanGen <Pers>
{
public :
virtual ~TriParAgeAsc (void) noexcept {}
virtual bool operator () (const Pers & p1, const Pers & p2)
const noexcept
{
return p1.getAge () < p2.getAge ();
} // operator ()
}; // TriParAgeAsc
class TriParNomDesc : public ILessThanGen <Pers>
{
public :
virtual ~TriParNomDesc (void) noexcept {}
virtual bool operator () (const Pers & p1, const Pers & p2)
const noexcept
{
return p1.getNom () > p2.getNom ();
} // operator ()
}; // TriParNomDesc
void functorSort (void)
{
cout << "FunctorSort : \n";
typedef vector <Pers> CVPers;
CVPers vPers;
vPers.push_back ( Pers ("Charlotte", 21));
vPers.push_back ( Pers ("Alfred", 12));
vPers.push_back ( Pers ("Jean", 42));
vPers.push_back ( Pers ("Noemie", 11));
vPers.push_back ( Pers ("Berthe", 99));
vPers.push_back ( Pers ("Agathe", 29));
vPers.push_back ( Pers ("Sylvain", 42));
vPers.push_back ( Pers ("Pierre", 75));
for (const Pers & personne : vPers)
cout << personne << '\n';
cout << "\nTri par age croissant\n\n";
quickSort (vPers.begin (), vPers.end (), TriParAgeAsc ());
for (const Pers & personne : vPers)
cout << personne << '\n';
cout << "\nTri par nom decroissant\n\n";
quickSort (vPers.begin (), vPers.end (), TriParNomDesc ());
for (const Pers & personne : vPers)
cout << personne << '\n';
} // functorSort()
} // namespace
int main (void)
{
functorSort ();
return 0;
} // main()