Hi Ashish,
Your solution worked perfectly, with a slight modification. Thank you very much, it really helped a lot. For the record, I'll leave my working program. Now I'll try to make it word with std::function and using lambdas... :-)
#include <iostream>
#include <string>
#include <list>
#include <functional>
#include <algorithm>
#include
using std::string;
using std::cout;
using std::endl;
using std::list;
using std::function;
using std::for_each;
using std::shared_ptr;
using boost::filter_iterator;
using boost::make_filter_iterator;
class employee;
class employee
{
public:
employee()
: income(0.0), age(0), manager(nullptr)
{ }
employee(const string& name, double income, int age, employee* manager)
: name(name), income(income), age(age), manager(manager)
{ }
employee(const employee& copy)
: name(copy.name), income(copy.income), age(copy.age), manager(copy.manager)
{ }
string manager_name() const {
return manager != nullptr ? manager->name : "[Sin jefe]";
}
void print() const { cout << name << endl; }
string name;
double income;
int age;
employee* manager;
};
struct range_func
{
range_func()
: _min(0), _max(0)
{ }
range_func(const range_func& copy)
: _min(copy._min), _max(copy._max)
{ }
range_func(int min, int max)
: _min(min), _max(max)
{ }
bool operator()(const employee& emp) const {
return _min <= emp.age && emp.age <= _max;
}
int _min;
int _max;
};
struct substr_func
{
substr_func()
{ }
substr_func(const string& str)
: _str(str)
{ }
substr_func(const substr_func& copy)
: _str(copy._str)
{ }
bool operator()(const employee& emp) const {
return emp.name.find(_str) != string::npos;
}
string _str;
};
struct mgr_func
{
mgr_func()
: _ptr(nullptr)
{ }
mgr_func(employee* ptr)
: _ptr(ptr)
{ }
mgr_func(const mgr_func& copy)
: _ptr(copy._ptr)
{ }
bool operator()(const employee& emp) const {
bool val = false;
if (_ptr == nullptr)
val = emp.manager == nullptr;
else
val = emp.manager_name() == _ptr->name;
return val;
}
employee* _ptr;
};
class catalog
{
public:
typedef list<employee> employee_list;
typedef employee_list::size_type size_type;
typedef employee_list::iterator iterator;
typedef employee_list::const_iterator const_iterator;
typedef filter_iterator<range_func,> range_filter_iterator;
typedef filter_iterator<substr_func,> substr_filter_iterator;
typedef filter_iterator<mgr_func,> mgr_filter_iterator;
private:
employee_list _employees;
public:
catalog() { }
size_type size() const { return _employees.size(); }
void clear() { _employees.clear(); }
void add(const employee& emp) { _employees.push_back(emp); }
void add(const string& name, double income, int age, employee* mgr) {
add(employee(name, income, age, mgr));
}
iterator begin_all() { return _employees.begin(); }
iterator end() { return _employees.end(); }
range_filter_iterator begin_age_range(int min, int max) {
return begin_age_range(range_func(min, max));
}
range_filter_iterator begin_age_range(const range_func& func) {
return make_filter_iterator<range_func>(func, _employees.begin(), _employees.end());
}
range_filter_iterator end_age_range(int min, int max) {
return end_age_range(range_func(min, max));
}
range_filter_iterator end_age_range(const range_func& func) {
return make_filter_iterator<range_func>(func, _employees.end(), _employees.end());
}
substr_filter_iterator begin_substr(const string& value) {
return begin_substr(substr_func(value));
}
substr_filter_iterator begin_substr(const substr_func& func) {
return make_filter_iterator(func, _employees.begin(), _employees.end());
}
substr_filter_iterator end_substr(const string& value) {
return end_substr(substr_func(value));
}
substr_filter_iterator end_substr(const substr_func& func) {
return make_filter_iterator(func, _employees.end(), _employees.end());
}
mgr_filter_iterator begin_mgr(employee* mgr) {
return begin_mgr(mgr_func(mgr));
}
mgr_filter_iterator begin_mgr(const mgr_func& func) {
return make_filter_iterator(func, _employees.begin(), _employees.end());
}
mgr_filter_iterator end_mgr(employee* mgr) {
return end_mgr(mgr_func(mgr));
}
mgr_filter_iterator end_mgr(const mgr_func& func) {
return make_filter_iterator(func, _employees.end(), _employees.end());
}
};
int main(int argc, char* argv[])
{
catalog cat;
employee fer("Fernando", 10000, 29, nullptr);
cat.add(fer);
cat.add("Gabriela", 13500, 26, &fer);
employee jime("Jimena", 9500, 22, &fer);
cat.add(jime);
cat.add("Mario", 4300, 37, &jime);
employee caty("Catalina", 15000, 31, nullptr);
cat.add(caty);
employee gis("Gisela", 14750, 30, &caty);
cat.add(gis);
cat.add("Omar", 12700, 30, &gis);
auto func = [](const employee& emp) {
emp.print();
};
cout << "*** Todos los empleados *** " << endl;
for_each(cat.begin_all(), cat.end(), func);
cout << endl;
cout << "***** POR EDAD *****" << endl;
cout << "Edad entre 25 y 30" << endl;
for_each(cat.begin_age_range(25, 30), cat.end_age_range(25, 30), func);
cout << endl;
cout << "Edad menor a 25" << endl;
for_each(cat.begin_age_range(0, 25), cat.end_age_range(0, 25), func);
cout << endl;
cout << "Edad mayor a 30" << endl;
for_each(cat.begin_age_range(30, 100), cat.end_age_range(30, 100), func);
cout << endl;
cout << "***** POR NOMBRE *****" << endl;
cout << "Nombre que contenga 'na'" << endl;
for_each(cat.begin_substr("na"), cat.end_substr("na"), func);
cout << endl;
cout << "Nombre que contenga 'ri'" << endl;
for_each(cat.begin_substr("ri"), cat.end_substr("ri"), func);
cout << endl;
cout << "***** POR JEFE *****" << endl;
cout << "Le reportan a Fernando" << endl;
for_each(cat.begin_mgr(&fer), cat.end_mgr(&fer), func);
cout << endl;
cout << "Le reportan a Caty" << endl;
for_each(cat.begin_mgr(&caty), cat.end_mgr(&caty), func);
cout << endl;
system("pause");
return 0;
}
</range_func></range_func></employee></algorithm></functional></list></string></iostream>
The output being:
*** Todos los empleados ***
Fernando
Gabriela
Jimena
Mario
Catalina
Gisela
Omar
***** POR EDAD *****
Edad entre 25 y 30
Fernando
Gabriela
Gisela
Omar
Edad menor a 25
Jimena
Edad mayor a 30
Mario
Catalina
Gisela
Omar
***** POR NOMBRE *****
Nombre que contenga 'na'
Fernando
Jimena
Catalina
Nombre que contenga 'ri'
Gabriela
Mario
***** POR JEFE *****
Le reportan a Fernando
Gabriela
Jimena
Le reportan a Caty
Gisela
Press any key to continue . . .