// **********************************************************************
//
// Copyright (c) 2002
// IONA Technologies, Inc.
// Waltham, MA, USA
//
// All Rights Reserved
//
// **********************************************************************

#ifndef OB_ALGORITHMS_H
#define OB_ALGORITHMS_H

#include <OB/STLConfig.h>

namespace OB
{

namespace stl
{

template<class InputIterator, class OutputIterator>
OutputIterator copy(InputIterator first1, InputIterator last1,
                    OutputIterator first2)
{
    while (first1 != last1)
    {
        *first2 = *first1;
        first1++;
        first2++;
    }

    return first2;
}

template<class InputIterator>
InputIterator find(InputIterator first, InputIterator last,
                   typename InputIterator::value_type value)
{
    while (first != last)
    {
        if (*first == value)
            return first;

        first++;
    }

    return first;
}

template<class InputIterator, class Predicate>
InputIterator find_if(InputIterator first, InputIterator last, Predicate pred)
{
    while (first != last)
    {
        if (pred(*first))
            return first;

        first++;
    }

    return first;
}

template<class InputIterator, class T>
T accumulate(InputIterator first, InputIterator last, T initial_value)
{
    T result = initial_value;
    
    while (first != last)
    {
        result = result + *first;
        first++;
    }

    return result;
}


template<class InputIterator, class T, class BinaryOperation>
T accumulate(InputIterator first, InputIterator last,
            T initial_value, BinaryOperation binary_op)
{
    T result = initial_value;
    
    while (first != last)
    {
        result = binary_op(result, *first);
        first++;
    }

    return result;
}


template<class ForwardIterator, class Predicate>
ForwardIterator remove_if(ForwardIterator first, ForwardIterator last,
                          Predicate pred)
{
    while (first != last)
    {
        if (!pred(*first))
        {
            typename ForwardIterator::value_type value = *first;
            last--;
            *first = *last;
            *last = value;
            continue;
        }

        first++;
    }

    return first;
}


template<class InputIterator, class UnaryFunction>
void for_each(InputIterator first, InputIterator last,
                       UnaryFunction f)
{
    while (first != last)
    {
        f(*first);
        first++;
    }
}

} // End namespace stl

} // End namespace OB


#endif
