#ifndef BITFUNCTIONAL__
#define BITFUNCTIONAL__

#include <functional>

/*
    Frank B. Brokken, july 19, 2001.
    f.b.brokken@rug.nl

    This file predefines function-objects that are non-standard. 

    The following function objects are defined:

        name                operator
        ----------------------------
        shift_left          <<
        shift_right         >>
        bit_not             ~
        bit_and             &
        bit_or              |
        bit_xor             ^
        ----------------------------

    In order to make these objects available, install this file in a directory
    where your compiler finds it, and let sources do:

        #include <bitfunctional>

    This include directive implies #include <functional>
*/

template <typename _Tp>
struct shift_left : public binary_function<_Tp,_Tp,_Tp> {
  _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x << __y; }
};

template <typename _Tp>
struct shift_right : public binary_function<_Tp,_Tp,_Tp> {
  _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x >> __y; }
};

template <typename _Tp>
struct bit_not : public unary_function<_Tp,_Tp> {
  _Tp operator()(const _Tp& __x) const { return ~__x; }
};

template <typename _Tp>
struct bit_and : public binary_function<_Tp,_Tp,_Tp> {
  _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x & __y; }
};

template <typename _Tp>
struct bit_or : public binary_function<_Tp,_Tp,_Tp> {
  _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x | __y; }
};

template <typename _Tp>
struct bit_xor : public binary_function<_Tp,_Tp,_Tp> {
  _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x ^ __y; }
};

#endif

