Wednesday, April 15, 2009

c++ stl – find_if and not1 used to fined vector item which is exception to the rule

//Author: Darius Kucinskas (c) 2008-2009
//Email: d[dot]kucinskas[eta]gmail[dot]com
//Blog: http://blog-of-darius.blogspot.com/
//License: GPL

#include <algorithm>
#include <vector>
#include <iostream>
#include <iterator>
#include <functional>

class Person
{
public:
    Person();
    Person(int a, std::string n);
    Person(const Person& src);

    bool Person::operator==(const Person& src);
    friend std::ostream& operator<<(std::ostream& out, const Person& person);

    int age;
    std::string name;
};

Person::Person()
: age(0)
, name("")
{};

Person::Person(int a, std::string n)
:age(a)
,name(n)
{};

Person::Person(const Person& src)
{
    age = src.age;
    name = src.name;
};

bool Person::operator==(const Person& src)
{
    if (name != src.name) return false;
    if (age != src.age) return false;
    return true;
}

std::ostream& operator<<(std::ostream& out, const Person& person)
{
    out << " Person name: '"
        << person.name
        << "' age: '"
        << person.age
        << "'";

    return out;
}

struct PersonOlderThen18: public std::unary_function<Person, bool>
{
    bool operator()(const Person& person) const
    {
        return (person.age >= 18);
    }
};

int main(int count, char** args)
{
    std::vector<Person> personVec;
    Person p1(18, "Person1");
    Person p2(20, "Person2");
    Person p3(12, "Person3");
    Person p4(21, "Person4");

    personVec.push_back(p1);
    personVec.push_back(p2);
    personVec.push_back(p3);
    personVec.push_back(p4);

    std::cout << std::endl;
    std::copy(personVec.begin(), personVec.end(), std::ostream_iterator<Person>(std::cout, "\n"));

    std::vector::const_iterator it;
    it = std::find_if(personVec.begin(), personVec.end(), std::not1(PersonOlderThen18()));
    if (it != personVec.end())
    {
        std::cout << std::endl;
        std::cout << " Found person (age < 18): " << *it << std::endl;
    }

    return 0;
}