前回の簡易ラムダを元にしてlambdaを作ってみました
現時点では、簡単な計算しかできません
(&&とか||で繋ぐこともできないし、%も使えない)
そのうちいろいろ修正するかも(しないかも)
サンプル(できること全部)
#include <iostream> #include <vector> #include <string> #include <algorithm> #include <shand/lambda.hpp> using namespace std; using namespace shand; struct person { int age; string name; person(int age, const string& name) : age(age), name(name) {} }; int main() { { vector<int> v; v.push_back(3); v.push_back(1); v.push_back(4); find_if(v.begin(), v.end(), lambda() < 2); find_if(v.begin(), v.end(), lambda() > 2); find_if(v.begin(), v.end(), lambda() <= 3); find_if(v.begin(), v.end(), lambda() >= 2); find_if(v.begin(), v.end(), lambda() == 3); find_if(v.begin(), v.end(), lambda() != 2); for_each(v.begin(), v.end(), lambda() = 2); for_each(v.begin(), v.end(), lambda() += 2); for_each(v.begin(), v.end(), lambda() -= 2); for_each(v.begin(), v.end(), lambda() *= 2); for_each(v.begin(), v.end(), lambda() /= 2); for_each(v.begin(), v.end(), cout << lambda()); } { vector<person> v; v.push_back(person(23, "Akira")); v.push_back(person(38, "Johnny")); v.push_back(person(16, "Millia")); find_if(v.begin(), v.end(), lambda(&person::age) < 20); find_if(v.begin(), v.end(), lambda(&person::age) > 20); find_if(v.begin(), v.end(), lambda(&person::age) <= 23); find_if(v.begin(), v.end(), lambda(&person::age) >= 20); find_if(v.begin(), v.end(), lambda(&person::age) == 38); find_if(v.begin(), v.end(), lambda(&person::age) != 20); for_each(v.begin(), v.end(), lambda(&person::age) = 20); for_each(v.begin(), v.end(), lambda(&person::age) += 20); for_each(v.begin(), v.end(), lambda(&person::age) -= 20); for_each(v.begin(), v.end(), lambda(&person::age) *= 20); for_each(v.begin(), v.end(), lambda(&person::age) /= 20); for_each(v.begin(), v.end(), cout << lambda(&person::name)); } return 0; }
ソース(shand/lambda.hpp)
#ifndef SHAND_LAMBDA_INCLUDE #define SHAND_LAMBDA_INCLUDE #include <ostream> #include <functional> namespace shand { namespace lambda_detail { #define CREATE_MEMBER_COMP_FUNCTOR(Class, Operator) \ template <class ClassName, class T, class U> \ class Class : public std::binary_function<ClassName, U, bool> { \ T ClassName::* member_; \ public: \ explicit Class(T ClassName::* member) \ : member_(member) {} \ \ bool operator()(const ClassName &lhs, const U &rhs) const \ { \ return lhs.*member_ Operator rhs; \ } \ }; CREATE_MEMBER_COMP_FUNCTOR(mem_less_functor, <); CREATE_MEMBER_COMP_FUNCTOR(mem_greater_functor, >); CREATE_MEMBER_COMP_FUNCTOR(mem_less_equal_functor, <=); CREATE_MEMBER_COMP_FUNCTOR(mem_greater_equal_functor, >=); CREATE_MEMBER_COMP_FUNCTOR(mem_equal_functor, ==); CREATE_MEMBER_COMP_FUNCTOR(mem_not_equal_functor, !=); #define CREATE_UNARY_FUNCTOR(Class, Operator) \ template <class T> \ class Class { \ T value_; \ public: \ explicit Class(const T& value) \ : value_(value) {} \ \ template <class U> \ void operator()(U& value) const \ { \ value Operator value_; \ } \ }; CREATE_UNARY_FUNCTOR(assign, =); CREATE_UNARY_FUNCTOR(plus_equal, +=); CREATE_UNARY_FUNCTOR(minus_equal, -=); CREATE_UNARY_FUNCTOR(multiply_equal, *=); CREATE_UNARY_FUNCTOR(divide_equal, /=); #define CREATE_MEM_UNARY_FUNCTOR(Class, Operator) \ template <class ClassName, class T, class U> \ class Class { \ T ClassName::* member_; \ U value_; \ public: \ explicit Class(T ClassName::* member, const U& value) \ : member_(member), value_(value) {} \ \ void operator()(ClassName& obj) \ { \ obj.*member_ Operator value_; \ } \ }; CREATE_MEM_UNARY_FUNCTOR(mem_assign, =); CREATE_MEM_UNARY_FUNCTOR(mem_plus_equal, +=); CREATE_MEM_UNARY_FUNCTOR(mem_minus_equal, -=); CREATE_MEM_UNARY_FUNCTOR(mem_multiply_equal, *=); CREATE_MEM_UNARY_FUNCTOR(mem_divide_equal, /=); class lambda_stream { std::ostream& os_; public: lambda_stream(std::ostream& os) : os_(os) {} template <class T> void operator()(const T& value) { os_ << value; } }; template <class ClassName, class T> class mem_lambda_stream { std::ostream& os_; T ClassName::* member_; public: mem_lambda_stream(T ClassName::* member, std::ostream& os) : member_(member), os_(os) {} void operator()(const ClassName& value) { os_ << value.*member_; } }; } // namespace shand::lambda_detail struct lambda_t { template <class T> friend std::binder2nd<std::less<T> > operator<(const lambda_t&, const T& value) { return std::bind2nd(std::less<T>(), value); } template <class T> friend std::binder2nd<std::greater<T> > operator>(const lambda_t&, const T& value) { return std::bind2nd(std::greater<T>(), value); } template <class T> friend std::binder2nd<std::less_equal<T> > operator<=(const lambda_t&, const T& value) { return std::bind2nd(std::less_equal<T>(), value); } template <class T> friend std::binder2nd<std::greater_equal<T> > operator>=(const lambda_t&, const T& value) { return std::bind2nd(std::greater_equal<T>(), value); } template <class T> friend std::binder2nd<std::equal_to<T> > operator==(const lambda_t&, const T& value) { return std::bind2nd(std::equal_to<T>(), value); } template <class T> friend std::binder2nd<std::not_equal_to<T> > operator!=(const lambda_t&, const T& value) { return std::bind2nd(std::not_equal_to<T>(), value); } template <class T> lambda_detail::assign<T> operator=(const T& value) { return lambda_detail::assign<T>(value); } template <class T> lambda_detail::plus_equal<T> operator+=(const T& value) { return lambda_detail::plus_equal<T>(value); } template <class T> lambda_detail::minus_equal<T> operator-=(const T& value) { return lambda_detail::minus_equal<T>(value); } template <class T> lambda_detail::multiply_equal<T> operator*=(const T& value) { return lambda_detail::multiply_equal<T>(value); } template <class T> lambda_detail::divide_equal<T> operator/=(const T& value) { return lambda_detail::divide_equal<T>(value); } }; template <class ClassName, class T> class mem_lambda_t { T ClassName::* member_; public: explicit mem_lambda_t(T ClassName::* member) : member_(member) {} template <class U> friend std::binder2nd<lambda_detail::mem_less_functor<ClassName, T, U> > operator<(const mem_lambda_t& func, const U& value) { return std::bind2nd(lambda_detail::mem_less_functor<ClassName, T, U>(func.member_), value); } template <class U> friend std::binder2nd<lambda_detail::mem_greater_functor<ClassName, T, U> > operator>(const mem_lambda_t& func, const U& value) { return std::bind2nd(lambda_detail::mem_greater_functor<ClassName, T, U>(func.member_), value); } template <class U> friend std::binder2nd<lambda_detail::mem_less_equal_functor<ClassName, T, U> > operator<=(const mem_lambda_t& func, const U& value) { return std::bind2nd(lambda_detail::mem_less_equal_functor<ClassName, T, U>(func.member_), value); } template <class U> friend std::binder2nd<lambda_detail::mem_greater_equal_functor<ClassName, T, U> > operator>=(const mem_lambda_t& func, const U& value) { return std::bind2nd(lambda_detail::mem_greater_equal_functor<ClassName, T, U>(func.member_), value); } template <class U> friend std::binder2nd<lambda_detail::mem_equal_functor<ClassName, T, U> > operator==(const mem_lambda_t& func, const U& value) { return std::bind2nd(lambda_detail::mem_equal_functor<ClassName, T, U>(func.member_), value); } template <class U> friend std::binder2nd<lambda_detail::mem_not_equal_functor<ClassName, T, U> > operator!=(const mem_lambda_t& func, const U& value) { return std::bind2nd(lambda_detail::mem_not_equal_functor<ClassName, T, U>(func.member_), value); } template <class U> lambda_detail::mem_assign<ClassName, T, U> operator=(const U& value) { return lambda_detail::mem_assign<ClassName, T, U>(member_, value); } template <class U> lambda_detail::mem_plus_equal<ClassName, T, U> operator+=(const U& value) { return lambda_detail::mem_plus_equal<ClassName, T, U>(member_, value); } template <class U> lambda_detail::mem_minus_equal<ClassName, T, U> operator-=(const U& value) { return lambda_detail::mem_minus_equal<ClassName, T, U>(member_, value); } template <class U> lambda_detail::mem_multiply_equal<ClassName, T, U> operator*=(const U& value) { return lambda_detail::mem_multiply_equal<ClassName, T, U>(member_, value); } template <class U> lambda_detail::mem_divide_equal<ClassName, T, U> operator/=(const U& value) { return lambda_detail::mem_divide_equal<ClassName, T, U>(member_, value); } template <class ClassNameU, class U> friend lambda_detail::mem_lambda_stream<ClassNameU, U> operator<<(std::ostream& os, const mem_lambda_t<ClassNameU, U>& ml); }; inline lambda_detail::lambda_stream operator<<(std::ostream& os, const lambda_t&) { return lambda_detail::lambda_stream(os); } template <class ClassName, class T> inline lambda_detail::mem_lambda_stream<ClassName, T> operator<<(std::ostream& os, const mem_lambda_t<ClassName, T>& ml) { return lambda_detail::mem_lambda_stream<ClassName, T>(ml.member_, os); } inline lambda_t lambda() { return lambda_t(); } template <class ClassName, class T> inline mem_lambda_t<ClassName, T> lambda(T ClassName::* member) { return mem_lambda_t<ClassName, T>(member); } } // namespace shand #endif // SHAND_LAMBDA_INCLUDE