Edit: /usr/include/boost/icl/functors.hpp (16489B)
/*-----------------------------------------------------------------------------+
Copyright (c) 2007-2009: Joachim Faulhaber
+------------------------------------------------------------------------------+
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENCE.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
+-----------------------------------------------------------------------------*/
#ifndef BOOST_ICL_FUNCTORS_HPP_JOFA_080315
#define BOOST_ICL_FUNCTORS_HPP_JOFA_080315
#include
#include
#include
#include
#include
#include
namespace boost{namespace icl
{
// ------------------------------------------------------------------------
template struct identity_based_inplace_combine
{
typedef Type& first_argument_type;
typedef const Type& second_argument_type;
typedef void result_type;
inline static Type identity_element() { return boost::icl::identity_element::value(); }
};
// ------------------------------------------------------------------------
template struct unit_element_based_inplace_combine
{
typedef Type& first_argument_type;
typedef const Type& second_argument_type;
typedef void result_type;
inline static Type identity_element() { return boost::icl::unit_element::value(); }
};
// ------------------------------------------------------------------------
template struct inplace_identity
: public identity_based_inplace_combine
{
typedef inplace_identity type;
void operator()(Type&, const Type&)const{}
};
template<>
inline std::string unary_template_to_string::apply()
{ return "i="; }
// ------------------------------------------------------------------------
template struct inplace_erasure
: public identity_based_inplace_combine
{
typedef inplace_erasure type;
typedef identity_based_inplace_combine base_type;
void operator()(Type& object, const Type& operand)const
{
if(object == operand)
//identity_element(); //JODO Old gcc-3.4.4 does not compile this
object = base_type::identity_element(); //<-- but this.
}
};
template<>
inline std::string unary_template_to_string::apply()
{ return "0="; }
// ------------------------------------------------------------------------
template struct inplace_plus
: public identity_based_inplace_combine
{
typedef inplace_plus type;
void operator()(Type& object, const Type& operand)const
{ object += operand; }
static void version(Type&){}
};
template<>
inline std::string unary_template_to_string::apply() { return "+="; }
// ------------------------------------------------------------------------
template struct inplace_minus
: public identity_based_inplace_combine
{
typedef inplace_minus type;
void operator()(Type& object, const Type& operand)const
{ object -= operand; }
};
template<>
inline std::string unary_template_to_string::apply() { return "-="; }
// ------------------------------------------------------------------------
template struct inplace_bit_add
: public identity_based_inplace_combine
{
typedef inplace_bit_add type;
void operator()(Type& object, const Type& operand)const
{ object |= operand; }
static void version(Type&){}
};
template<>
inline std::string unary_template_to_string::apply() { return "b|="; }
// ------------------------------------------------------------------------
template struct inplace_bit_subtract
: public identity_based_inplace_combine
{
typedef inplace_bit_subtract type;
void operator()(Type& object, const Type& operand)const
{ object &= ~operand; }
};
template<>
inline std::string unary_template_to_string::apply() { return "b-="; }
// ------------------------------------------------------------------------
template struct inplace_bit_and
: public identity_based_inplace_combine
{
typedef inplace_bit_and type;
void operator()(Type& object, const Type& operand)const
{ object &= operand; }
};
template<>
inline std::string unary_template_to_string::apply() { return "b&="; }
// ------------------------------------------------------------------------
template struct inplace_bit_xor
: public identity_based_inplace_combine
{
typedef inplace_bit_xor type;
void operator()(Type& object, const Type& operand)const
{ object ^= operand; }
};
// ------------------------------------------------------------------------
template struct inplace_et
: public identity_based_inplace_combine
{
typedef inplace_et type;
void operator()(Type& object, const Type& operand)const
{ object &= operand; }
};
template<>
inline std::string unary_template_to_string::apply() { return "&="; }
// ------------------------------------------------------------------------
template struct inplace_caret
: public identity_based_inplace_combine
{
typedef inplace_caret type;
void operator()(Type& object, const Type& operand)const
{ object ^= operand; }
};
template<>
inline std::string unary_template_to_string::apply() { return "^="; }
// ------------------------------------------------------------------------
template struct inplace_insert
: public identity_based_inplace_combine
{
typedef inplace_insert type;
void operator()(Type& object, const Type& operand)const
{ insert(object,operand); }
};
template<>
inline std::string unary_template_to_string::apply() { return "ins="; }
// ------------------------------------------------------------------------
template struct inplace_erase
: public identity_based_inplace_combine
{
typedef inplace_erase type;
void operator()(Type& object, const Type& operand)const
{ erase(object,operand); }
};
template<>
inline std::string unary_template_to_string::apply() { return "ers="; }
// ------------------------------------------------------------------------
template struct inplace_star
: public identity_based_inplace_combine //JODO unit_element_
{
typedef inplace_star type;
void operator()(Type& object, const Type& operand)const
{ object *= operand; }
};
template<>
inline std::string unary_template_to_string::apply() { return "*="; }
// ------------------------------------------------------------------------
template struct inplace_slash
: public identity_based_inplace_combine //JODO unit_element_
{
typedef inplace_slash type;
void operator()(Type& object, const Type& operand)const
{ object /= operand; }
};
template<>
inline std::string unary_template_to_string::apply() { return "/="; }
// ------------------------------------------------------------------------
template struct inplace_max
: public identity_based_inplace_combine
{
typedef inplace_max type;
void operator()(Type& object, const Type& operand)const
{
if(object < operand)
object = operand;
}
};
template<>
inline std::string unary_template_to_string::apply() { return "max="; }
// ------------------------------------------------------------------------
template struct inplace_min
: public identity_based_inplace_combine
{
typedef inplace_min type;
void operator()(Type& object, const Type& operand)const
{
if(object > operand)
object = operand;
}
};
template<>
inline std::string unary_template_to_string::apply() { return "min="; }
//--------------------------------------------------------------------------
// Inter_section functor
//--------------------------------------------------------------------------
template struct inter_section
: public identity_based_inplace_combine
{
typedef typename boost::mpl::
if_,
icl::inplace_et,
icl::inplace_plus
>::type
type;
void operator()(Type& object, const Type& operand)const
{
type()(object, operand);
}
};
//--------------------------------------------------------------------------
// Inverse functor
//--------------------------------------------------------------------------
template struct inverse;
template
struct inverse >
{ typedef icl::inplace_minus type; };
template
struct inverse >
{ typedef icl::inplace_plus type; };
template
struct inverse >
{ typedef icl::inplace_bit_subtract type; };
template
struct inverse >
{ typedef icl::inplace_bit_add type; };
template
struct inverse >
{ typedef icl::inplace_caret type; };
template
struct inverse >
{ typedef icl::inplace_et type; };
template
struct inverse >
{ typedef icl::inplace_bit_xor type; };
template
struct inverse >
{ typedef icl::inplace_bit_and type; };
template
struct inverse >
{ typedef icl::inplace_slash type; };
template
struct inverse >
{ typedef icl::inplace_star type; };
template
struct inverse >
{ typedef icl::inplace_min type; };
template
struct inverse >
{ typedef icl::inplace_max type; };
template
struct inverse >
{ typedef icl::inplace_erasure type; };
// If a Functor
template
struct inverse
{
typedef typename
remove_reference::type argument_type;
typedef icl::inplace_erasure type;
};
//--------------------------------------------------------------------------
// Inverse inter_section functor
//--------------------------------------------------------------------------
template
struct inverse >
: public identity_based_inplace_combine
{
typedef typename boost::mpl::
if_,
icl::inplace_caret,
icl::inplace_minus
>::type
type;
void operator()(Type& object, const Type& operand)const
{
type()(object, operand);
}
};
//--------------------------------------------------------------------------
// Positive or negative functor trait
//--------------------------------------------------------------------------
// A binary operation - is negative (or inverting) with respect to the
// neutral element iff it yields the inverse element if it is applied to the
// identity element:
// 0 - x = -x
// For a functor that wraps the inplace of op-assign version this is
// equivalent to
//
// T x = ..., y;
// y = Functor::identity_element();
// Functor()(y, x); // y == inverse_of(x)
template struct is_negative;
template
struct is_negative
{
typedef is_negative type;
BOOST_STATIC_CONSTANT(bool, value = false);
};
template
struct is_negative >
{
typedef is_negative type;
BOOST_STATIC_CONSTANT(bool, value = true);
};
template
struct is_negative >
{
typedef is_negative type;
BOOST_STATIC_CONSTANT(bool, value = true);
};
//--------------------------------------------------------------------------
// Pro- or in-version functor
//--------------------------------------------------------------------------
template struct conversion;
template
struct conversion
{
typedef conversion type;
typedef typename
remove_const<
typename remove_reference::type
>::type
argument_type;
// The proversion of an op-assign functor o= lets the value unchanged
// (0 o= x) == x;
// Example += : (0 += x) == x
static argument_type proversion(const argument_type& value)
{
return value;
}
// The inversion of an op-assign functor o= inverts the value x
// to it's inverse element -x
// (0 o= x) == -x;
// Example -= : (0 -= x) == -x
static argument_type inversion(const argument_type& value)
{
argument_type inverse = Combiner::identity_element();
Combiner()(inverse, value);
return inverse;
}
};
template struct version : public conversion
{
typedef version type;
typedef conversion base_type;
typedef typename base_type::argument_type argument_type;
argument_type operator()(const argument_type& value)
{ return base_type::proversion(value); }
};
template<>struct version >{short operator()(short val){return -val;}};
template<>struct version >{int operator()(int val){return -val;}};
template<>struct version >{long operator()(long val){return -val;}};
template<>struct version >{long long operator()(long long val){return -val;}};
template<>struct version >{float operator()(float val){return -val;}};
template<>struct version >{double operator()(double val){return -val;}};
template<>struct version >{long double operator()(long double val){return -val;}};
template
struct version > : public conversion >
{
typedef version > type;
typedef conversion > base_type;
typedef typename base_type::argument_type argument_type;
Type operator()(const Type& value)
{
return base_type::inversion(value);
}
};
}} // namespace icl boost
#endif