mirror of
https://gitlab.com/fbb-git/cppannotations
synced 2024-11-16 07:48:44 +01:00
4a51c31ab9
git-svn-id: https://cppannotations.svn.sourceforge.net/svnroot/cppannotations/trunk@23 f6dd340e-d3f9-0310-b409-bdd246841980
158 lines
4.1 KiB
C++
158 lines
4.1 KiB
C++
#include <stdlib.h> // for qsort()
|
|
|
|
class Date;
|
|
|
|
class Person
|
|
{
|
|
public:
|
|
size_t length() const;
|
|
size_t weight() const;
|
|
char const *name() const;
|
|
char const *city() const;
|
|
Date const &birthdate() const;
|
|
|
|
private:
|
|
// all necessary data members
|
|
};
|
|
|
|
class Person_dbase
|
|
{
|
|
public:
|
|
enum Listtype
|
|
{
|
|
list_by_length,
|
|
list_by_weight,
|
|
list_by_name,
|
|
list_by_city,
|
|
list_by_birthday,
|
|
};
|
|
|
|
// ... constructors etc.
|
|
|
|
void list(Listtype type);
|
|
// list the information
|
|
private:
|
|
struct CmpPerson
|
|
{
|
|
union Compare_function
|
|
{
|
|
int (*persons)// comparing two Persons
|
|
(Person const *p1, Person const *p2);
|
|
int (*voids)// for qsort()
|
|
(void const *p1, void const *p2);
|
|
}
|
|
cmp;
|
|
|
|
#define u2c(a) static_cast<char const *(Person::*)() const>\
|
|
(size_t (Person::*##a)() const)
|
|
|
|
union Person_accessor
|
|
{
|
|
char const
|
|
*(Person::*cp)() const;
|
|
int
|
|
(Person::*i)() const;
|
|
Date const
|
|
&(Person::*d)() const;
|
|
}
|
|
pf; // to Person's access functions
|
|
};
|
|
|
|
static CmpPerson
|
|
cmpPerson[];
|
|
static Listtype
|
|
selector;
|
|
|
|
static int cmpstr(Person const *p1,
|
|
Person const *p2);
|
|
|
|
static int cmpint(Person const *p1,
|
|
Person const *p2);
|
|
|
|
static int cmpdate(Person const *p1,
|
|
Person const *p2);
|
|
|
|
Person
|
|
*pp; // pointer to the info
|
|
size_t
|
|
n; // number of persons stored.
|
|
};
|
|
|
|
void Person_dbase::list(Listtype type)
|
|
{
|
|
selector = type;
|
|
qsort(pp, n, sizeof(Person), cmpPerson[type].cmp.voids);
|
|
// list the sorted Person-database (to be implemented)
|
|
}
|
|
|
|
#define ccp(a) reinterpret_cast<char const *(Person::*)() const>(##a)
|
|
|
|
Person_dbase::CmpPerson
|
|
Person_dbase::cmpPerson[] =
|
|
{
|
|
{ // compare- and access
|
|
// function to compare length
|
|
cmpint,
|
|
// reinterpret_cast<char const *(Person::*)() const>
|
|
ccp(&Person::length),
|
|
},
|
|
|
|
{ // same for weight
|
|
cmpint,
|
|
reinterpret_cast<char const *(Person::*)() const>
|
|
(&Person::weight)
|
|
},
|
|
|
|
{ // same for name
|
|
cmpstr,
|
|
&Person::name,
|
|
},
|
|
|
|
{ // same for city
|
|
cmpstr,
|
|
&Person::city,
|
|
},
|
|
|
|
{ // same for Date
|
|
cmpdate,
|
|
reinterpret_cast<char const *(Person::*)() const>
|
|
(&Person::birthdate),
|
|
},
|
|
};
|
|
|
|
int Person_dbase::cmpstr(Person const *p1, Person const *p2)
|
|
{
|
|
return
|
|
(
|
|
strcmp
|
|
(
|
|
(p1->*cmpPerson[selector].pf.cp)(),
|
|
(p2->*cmpPerson[selector].pf.cp)()
|
|
)
|
|
);
|
|
}
|
|
|
|
int Person_dbase::cmpint(Person const *p1, Person const *p2)
|
|
{
|
|
return
|
|
(
|
|
(p1->*cmpPerson[selector].pf.i)()
|
|
-
|
|
(p2->*cmpPerson[selector].pf.i)()
|
|
);
|
|
}
|
|
|
|
int Person_dbase::cmpdate(Person const *p1, Person const *p2)
|
|
{
|
|
return
|
|
(
|
|
(p1->*cmpPerson[selector].pf.d)()
|
|
<
|
|
(p2->*cmpPerson[selector].pf.d)() ?
|
|
-1
|
|
:
|
|
(p1->*cmpPerson[selector].pf.d)()
|
|
>
|
|
(p2->*cmpPerson[selector].pf.d)()
|
|
);
|
|
}
|