]> git.llucax.com Git - z.facultad/75.29/susanita.git/blob - src/persona.cpp
Bugfix.
[z.facultad/75.29/susanita.git] / src / persona.cpp
1 #include "persona.h"
2 #include <algorithm>
3 #include <cassert>
4
5 /// Constructor
6 Persona::
7 Persona(const std::string& nombre, sexo_type sexo):
8         nombre(nombre), estado(SOLTERO), sexo(sexo), pareja(0)
9 {
10 }
11
12 /// Para representación
13 std::ostream&
14 operator<< (std::ostream& os, const Persona::estado_type e)
15 {
16         switch (e)
17         {
18                 case Persona::SOLTERO:
19                         return os << "soltero";
20                 case Persona::DECLARADO:
21                         return os << "declarado";
22                 case Persona::COMPROMETIDO:
23                         return os << "comprometido";
24                 default:
25                         assert("Estado de la persona desconocido");
26                         return os << "desconocido";
27         }
28 }
29
30 /// Para representación
31 std::ostream&
32 operator<< (std::ostream& os, const Persona::sexo_type s)
33 {
34         switch (s)
35         {
36                 case Persona::M:
37                         return os << "M";
38                 case Persona::F:
39                         return os << "F";
40                 default:
41                         assert("Sexo de la persona desconocido");
42                         return os << "desconocido";
43         }
44 }
45
46 /// Para representación
47 std::ostream&
48 operator<< (std::ostream& os, const Persona& p)
49 {
50         std::string pareja = "-";
51         if (p.pareja)
52         {
53                 pareja = p.pareja->nombre;
54         }
55         os << "<" << p.nombre << " (" << p.sexo << "): " << p.estado << " - "
56                 << pareja << ">";
57         return os;
58 }
59
60 /// Función de comparación entre dos personas según nuestras preferencias
61 bool
62 Persona::
63 cmp(const Persona& p1, const Persona& p2) const
64 {
65         prefs_type::const_iterator pos_p1
66                 = std::find(prefs.begin(), prefs.end(), &p1);
67         prefs_type::const_iterator pos_p2
68                 = std::find(prefs.begin(), prefs.end(), &p2);
69         if (pos_p1 < pos_p2)
70                 return 1;
71         if (pos_p1 == pos_p2)
72                 return 0;
73         return -1;
74 }
75
76 // Para que no se exporte el símbolo, es de uso interno de este módulo
77 namespace
78 {
79         /// Functor de ordenamiento auxiliar
80         struct PersonaCmp
81         {
82                 Persona& p;
83                 PersonaCmp(Persona& p): p(p) {}
84                 /// devuelve true si p1 < p2
85                 bool operator ()(const Persona* const p1, const Persona* const p2)
86                 {
87                         return p.cmp(*p1, *p2) < 0;
88                 }
89         };
90 }
91
92 /// Ordenamos las ofertas segun nuestras preferencias
93 void
94 Persona::
95 ordenar_ofertas()
96 {
97         // este sort es in-place y O(N.log(N))
98         // Más info en: http://www.sgi.com/tech/stl/sort.html
99         std::sort(ofertas.begin(), ofertas.end(), PersonaCmp(*this));
100 }
101
102 /// Nos declaramos a la persona p
103 void
104 Persona::
105 declarar_a(Persona& p)
106 {
107         estado = DECLARADO;
108         pareja = &p;
109         p.ofertas.push_back(this);
110 }
111
112 /// Nos comprometemos con la persona p, quien se nos habia declarado previamente
113 void
114 Persona::
115 comprometer_con(Persona& p)
116 {
117         assert(p.estado == DECLARADO);
118         assert(p.pareja == this);
119
120         // rompemos el compromiso, si hay
121         if (estado == COMPROMETIDO)
122         {
123                 assert(pareja != 0);
124                 pareja->estado = SOLTERO;
125                 pareja->pareja = 0;
126                 pareja->rechazos.push_back(this);
127         }
128
129         // nos comprometemos
130         estado = COMPROMETIDO;
131         pareja = &p;
132         p.estado = COMPROMETIDO;
133         p.pareja = this;
134
135         // si tenemos ofertas, las rechazamos
136         for (ofertas_type::iterator pretendiente = ofertas.begin();
137                         pretendiente != ofertas.end(); ++pretendiente)
138         {
139                 (*pretendiente)->rechazos.push_back(this);
140         }
141         ofertas.clear();
142 }
143
144 // Nos comprometemos con la otra persona y a ella la comprometemos con nosotros
145 void
146 Persona::
147 comprometer_con_bt(Persona& p)
148 {
149         // nos comprometemos
150         estado = COMPROMETIDO;
151         pareja = &p;
152         p.estado = COMPROMETIDO;
153         p.pareja = this;
154 }
155
156 // Rompemos el compromiso existente
157 void
158 Persona::
159 romper_compromiso(Persona& p)
160 {
161         assert(pareja == &p);
162         assert(p.pareja == this);
163         
164         // rompemos el compromiso
165         estado = SOLTERO;
166         pareja = 0;
167         p.estado = SOLTERO;
168         p.pareja = 0;
169 }
170
171