Boost logo

Boost :

From: Nicolai Josuttis (nicolai.josuttis_at_[hidden])
Date: 1998-12-21 15:18:43


Hi,
attached is my first version of function object adapters for boost.
You can also find these three files at
        http://www.josuttis.de/cppcode/

Still missing are some examples for motivation.
However, this is a first version to get some first feedback.
Be honest!

Sean, how should I mention your name because you found the
names for these compose function object adapters?

Happy holidays

-- 
Nicolai M. Josuttis
Solutions in Time
http://www.josuttis.de/
solutions_at_[hidden]
------------------------------------------------------------------------
E-group home: http://www.eGroups.com/list/boost
Free Web-based e-mail groups by eGroups.com



/* Compose Function Object Adapters
 *
 * The C++ standard library does not provide enough
 * adapters to support functional composition.
 * For example, it is not possible to combine the
 * result of two unary operations to formulate
 * a criterion such as "this and/or that".
 * The following compose function objects close this gap.
 *
 * This code is provided "as is" without any express or implied warranty.
 * You can use it for free, provided this copyright notice appears.
 */
#ifndef COMPOSE_HPP
#define COMPOSE_HPP

#include <functional>

namespace boost {

/********************************************************
 * compose(op1,op2)
 * - processes:
 * op1(op2(value))
 */
template <class OP1, class OP2>
class compose_object
 : public std::unary_function<typename OP2::argument_type,
                              typename OP1::result_type>
{
  private:
    OP1 op1; // process: op1(op2(x))
    OP2 op2;
  public:
    // constructor
    compose_object(const OP1& o1, const OP2& o2)
     : op1(o1), op2(o2) {
    }

    // function call
    typename OP1::result_type
    operator()(const typename OP2::argument_type& x) const {
        return op1(op2(x));
    }
};

// convenience function for the compose adapter
template <class OP1, class OP2>
inline compose_object<OP1,OP2>
compose (const OP1& o1, const OP2& o2) {
    return compose_object<OP1,OP2>(o1,o2);
}

/********************************************************
 * inject_compose(op1,op2,op3)
 * - processes:
 * op1(op2(value),op3(value))
 */
template <class OP1, class OP2, class OP3>
class inject_compose_object
 : public std::unary_function<typename OP2::argument_type,
                              typename OP1::result_type>
{
  private:
    OP1 op1; // process: op1(op2(x),op3(x))
    OP2 op2;
    OP3 op3;
  public:
    // constructor
    inject_compose_object (const OP1& o1, const OP2& o2, const OP3& o3)
     : op1(o1), op2(o2), op3(o3) {
    }

    // function call
    typename OP1::result_type
    operator()(const typename OP2::argument_type& x) const {
        return op1(op2(x),op3(x));
    }
};

// convenience function for the compose adapter
template <class OP1, class OP2, class OP3>
inline inject_compose_object<OP1,OP2,OP3>
inject_compose (const OP1& o1, const OP2& o2, const OP3& o3) {
    return inject_compose_object<OP1,OP2,OP3>(o1,o2,o3);
}

/********************************************************
 * distr_compose(op1,op2,op3)
 * - processes:
 * op1(op2(value1),op3(value2))
 */
template <class OP1, class OP2, class OP3>
class distr_compose_object
 : public std::binary_function<typename OP2::argument_type,
                               typename OP3::argument_type,
                               typename OP1::result_type>
{
  private:
    OP1 op1; // process: op1(op2(x),op3(y))
    OP2 op2;
    OP3 op3;
  public:
    // constructor
    distr_compose_object (const OP1& o1, const OP2& o2, const OP3& o3)
     : op1(o1), op2(o2), op3(o3) {
    }

    // function call
    typename OP1::result_type
    operator()(const typename OP2::argument_type& x,
               const typename OP3::argument_type& y) const {
        return op1(op2(x),op3(y));
    }
};

// convenience function for the compose adapter
template <class OP1, class OP2, class OP3>
inline distr_compose_object<OP1,OP2,OP3>
distr_compose (const OP1& o1, const OP2& o2, const OP3& o3) {
    return distr_compose_object<OP1,OP2,OP3>(o1,o2,o3);
}

/********************************************************
 * binary_compose(op1,op2)
 * - processes:
 * op1(op2(value1,value2))
 */
template <class OP1, class OP2>
class binary_compose_object
 : public std::binary_function<typename OP2::first_argument_type,
                               typename OP2::second_argument_type,
                               typename OP1::result_type>
{
  private:
    OP1 op1; // process: op1(op2(x,y))
    OP2 op2;
  public:
    // constructor
    binary_compose_object (const OP1& o1, const OP2& o2)
     : op1(o1), op2(o2) {
    }

    // function call
    typename OP1::result_type
    operator()(const typename OP2::first_argument_type& x,
               const typename OP2::second_argument_type& y) const {
        return op1(op2(x,y));
    }
};

// convenience function for the compose adapter
template <class OP1, class OP2>
inline binary_compose_object<OP1,OP2>
binary_compose (const OP1& o1, const OP2& o2) {
    return binary_compose_object<OP1,OP2>(o1,o2);
}

} // namespace boost
#endif /*COMPOSE_HPP*/

------------------------------------------------------------------------
E-group home: http://www.eGroups.com/list/boost
Free Web-based e-mail groups by eGroups.com


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk