Привет Всем!
Наваял я тут на досуге смесь гремучую из шаблонов и макросов, что-бы понятнее и красивее код был.
Вместо:
typedef set<int, greater_equal<int> > IntSet;
можно писать:
typedef set<int, OP(>=)<int> > IntSet;
И даже так:
int s = 1;
s = accumulate(intSet.begin(), intSet.end(), s, OP(|)<int>());
Тестил я это на VC 6.0. Интересно, как это будет на других компиляторах?
А теперь сам код:
//#include "StlFunctional.h"
// Copyleft (X) 2003 by Vladimir E. Lipatov (WoldemaR).
#if _MSC_VER > 1000
#pragma once
#endif
#if !defined(STL_FUNCTIONAL_INCLUDE)
#define STL_FUNCTIONAL_INCLUDE
#pragma warning (disable : 4786)
#include <functional>
struct StlOperators//As namespace for hide into Workspace ClassView
{
template<int tOperator>
struct unaryOperator
{
template<typename _Ty>
struct Functional
{virtual Undefined_tOperator()=0;};
};
template<int tOperator>
struct binaryOperator
{
template<typename _Ty>
struct Functional
{virtual Undefined_tOperator()=0;};
};
#define DECLARE_STL_OPERATOR(type, optor, functional)\
template<>\
struct type##Operator<#@optor>\
{ template<typename _Ty>\
struct Functional : public std::##functional<_Ty>{};\
};
DECLARE_STL_OPERATOR(binary, +, plus);
DECLARE_STL_OPERATOR(binary, -, minus);
DECLARE_STL_OPERATOR(binary, *, multiplies);
DECLARE_STL_OPERATOR(binary, /, divides);
DECLARE_STL_OPERATOR(binary, %, modulus);
DECLARE_STL_OPERATOR(unary, -, negate);
DECLARE_STL_OPERATOR(binary, ==, equal_to);
DECLARE_STL_OPERATOR(binary, !=, not_equal_to);
DECLARE_STL_OPERATOR(binary, >, greater);
DECLARE_STL_OPERATOR(binary, <, less);
DECLARE_STL_OPERATOR(binary, >=, greater_equal);
DECLARE_STL_OPERATOR(binary, <=, less_equal);
DECLARE_STL_OPERATOR(binary, &&, logical_and);
DECLARE_STL_OPERATOR(binary, ||, logical_or);
DECLARE_STL_OPERATOR(unary, !, logical_not);
// Extension for binary
#define IMPLEMENT_EXB_OPERATOR(optor)\
template<>\
struct binaryOperator<#@optor>\
{ template<typename _Ty>\
struct Functional : public std::binary_function<_Ty, _Ty, _Ty>\
{_Ty operator()(const _Ty& _X, const _Ty& _Y) const\
{return (_X optor _Y); };\
};\
};
IMPLEMENT_EXB_OPERATOR(|);// Bitwise-Inclusive-OR Operator
IMPLEMENT_EXB_OPERATOR(&);// Bitwise-AND Operator
IMPLEMENT_EXB_OPERATOR(^);// Bitwise-Exclusive-OR Operator
IMPLEMENT_EXB_OPERATOR(<<);// Bitwise Left Shift and Right Shift Operators
IMPLEMENT_EXB_OPERATOR(>>);
};// StlOperators
#define OPU(operator) StlOperators::unaryOperator<#@operator>::Functional
#define OPB(operator) StlOperators::binaryOperator<#@operator>::Functional
#define OP(operator) OPB(operator)
#endif // !defined(STL_FUNCTIONAL_INCLUDE)
Небольшое дополнение.
Вся хитрость основана на том, что можно проинициализировать int таким образом:
int nVal = '<'; // До 4-ёх символов.
Ну и плюс специализация шаблона-обёртки.
Кроме того, я добавил реализации битовых операций, которых в <functional> нет.
Пользуйтесь на здоровье.
Следущая версия.
Добавлены операторы для указателей.
//#include "StlFunctional.h"
// Copyleft (X) 2003 by Vladimir E. Lipatov (WoldemaR).
#if _MSC_VER > 1000
#pragma once
#endif
#if !defined(STL_FUNCTIONAL_INCLUDE)
#define STL_FUNCTIONAL_INCLUDE
#pragma warning (disable : 4786)
#include <functional>
struct StlOperators//As namespace for hide into Workspace ClassView
{
template<int tOperator>
struct unaryOperator
{
template<typename _Ty>
struct Functional
{virtual Undefined_tOperator()=0;};
};
template<int tOperator>
struct binaryOperator
{
template<typename _Ty>
struct Functional
{virtual Undefined_tOperator()=0;};
};
#define DECL_STL_OPTOR(type, optor, functional)\
template<>\
struct type##Operator<#@optor>\
{ template<typename _Ty>\
struct Functional : public std::##functional<_Ty>{};\
};
DECL_STL_OPTOR(binary, +, plus);
DECL_STL_OPTOR(binary, -, minus);
DECL_STL_OPTOR(binary, *, multiplies);
DECL_STL_OPTOR(binary, /, divides);
DECL_STL_OPTOR(binary, %, modulus);
DECL_STL_OPTOR(unary, -, negate);
DECL_STL_OPTOR(binary, ==, equal_to);
DECL_STL_OPTOR(binary, !=, not_equal_to);
DECL_STL_OPTOR(binary, >, greater);
DECL_STL_OPTOR(binary, <, less);
DECL_STL_OPTOR(binary, >=, greater_equal);
DECL_STL_OPTOR(binary, <=, less_equal);
DECL_STL_OPTOR(binary, &&, logical_and);
DECL_STL_OPTOR(binary, ||, logical_or);
DECL_STL_OPTOR(unary, !, logical_not);
// Extension for binary
#define IMPL_EXB_OPTOR(optor)\
template<>\
struct binaryOperator<#@optor>\
{ template<typename _Ty>\
struct Functional : public std::binary_function<_Ty, _Ty, _Ty>\
{_Ty operator()(const _Ty& _X, const _Ty& _Y) const\
{return (_X optor _Y); };\
};\
};
IMPL_EXB_OPTOR(|);// Bitwise-Inclusive-OR Operator
IMPL_EXB_OPTOR(&);// Bitwise-AND Operator
IMPL_EXB_OPTOR(^);// Bitwise-Exclusive-OR Operator
IMPL_EXB_OPTOR(<<);// Bitwise Left Shift and Right Shift Operators
IMPL_EXB_OPTOR(>>);
#define IMPL_EXU_OPTOR(optor)\
template<>\
struct unaryOperator<#@optor>\
{ template<typename _Ty>\
struct Functional : public std::unary_function<_Ty, _Ty>\
{_Ty operator()(const _Ty& _X) const\
{return (optor _X); };\
};\
};
IMPL_EXU_OPTOR(~);//One's Complement Operator
// Extension for pointer
template<int tOperator>
struct binaryPointerOperator
{
template<typename _Ty>
struct Functional
{virtual Undefined_tOperator()=0;};
};
#define IMPL_EXPB_OPTOR(optor)\
template<>\
struct binaryPointerOperator<#@optor>\
{ template<typename _Ty>\
struct Functional : public std::binary_function<_Ty, _Ty, _Ty>\
{_Ty operator()(const _Ty& _X, const _Ty& _Y) const\
{return (*_X optor *_Y); };\
};\
};
IMPL_EXPB_OPTOR(+);
IMPL_EXPB_OPTOR(-);
IMPL_EXPB_OPTOR(*);
IMPL_EXPB_OPTOR(/);
IMPL_EXPB_OPTOR(%);
IMPL_EXPB_OPTOR(&&);
IMPL_EXPB_OPTOR(||);
IMPL_EXPB_OPTOR(|);
IMPL_EXPB_OPTOR(&);
IMPL_EXPB_OPTOR(^);
IMPL_EXPB_OPTOR(<<);
IMPL_EXPB_OPTOR(>>);
#define IMPL_EXPB_OPTOR_B(optor)\
template<>\
struct binaryPointerOperator<#@optor>\
{ template<typename _Ty>\
struct Functional : public std::binary_function<_Ty, _Ty, bool>\
{bool operator()(const _Ty& _X, const _Ty& _Y) const\
{return (*_X optor *_Y); };\
};\
template<>\
struct Functional<LPCTSTR> : public std::binary_function<LPCTSTR, LPCTSTR, bool>\
{bool operator()(LPCTSTR _X, LPCTSTR _Y) const\
{return (0 optor _tcscmp(_X, _Y)); };\
};\
};
IMPL_EXPB_OPTOR_B(==);
IMPL_EXPB_OPTOR_B(!=);
IMPL_EXPB_OPTOR_B(>);
IMPL_EXPB_OPTOR_B(<);
IMPL_EXPB_OPTOR_B(>=);
IMPL_EXPB_OPTOR_B(<=);
template<int tOperator>
struct unaryPointerOperator
{
template<typename _Ty>
struct Functional
{virtual Undefined_tOperator()=0;};
};
#define IMPL_EXPU_OPTOR(optor)\
template<>\
struct unaryPointerOperator<#@optor>\
{ template<typename _Ty>\
struct Functional : public std::unary_function<_Ty, _Ty>\
{_Ty operator()(const _Ty& _X) const\
{return (optor *_X); };\
};\
};
IMPL_EXPU_OPTOR(-);
IMPL_EXPU_OPTOR(!);
IMPL_EXPU_OPTOR(~);
};// StlOperators
#define OPU(optor) StlOperators::unaryOperator<#@optor>::Functional
#define OPB(optor) StlOperators::binaryOperator<#@optor>::Functional
#define OP(optor) OPB(optor)
#define OPPU(optor) StlOperators::unaryPointerOperator<#@optor>::Functional
#define OPPB(optor) StlOperators::binaryPointerOperator<#@optor>::Functional
#define OPP(optor) OPPB(optor)
#endif // !defined(STL_FUNCTIONAL_INCLUDE)