1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- // Copyright (C) 2009-2012 Lorenzo Caminiti
- // Distributed under the Boost Software License, Version 1.0
- // (see accompanying file LICENSE_1_0.txt or a copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- // Home at http://www.boost.org/libs/local_function
- //[impl_tparam_tricks
- #include <boost/detail/lightweight_test.hpp>
- #include <vector>
- #include <algorithm>
- // Casting functor trick.
- struct casting_func {
- explicit casting_func(void* obj, void (*call)(void*, const int&))
- : obj_(obj), call_(call) {}
- // Unfortunately, function pointer call is not inlined.
- inline void operator()(const int& num) { call_(obj_, num); }
- private:
- void* obj_;
- void (*call_)(void*, const int&);
- };
- // Virtual functor trick.
- struct virtual_func {
- struct interface {
- // Unfortunately, virtual function call is not inlined.
- inline virtual void operator()(const int&) {}
- };
- explicit virtual_func(interface& func): func_(&func) {}
- inline void operator()(const int& num) { (*func_)(num); }
- private:
- interface* func_;
- };
- int main(void) {
- int sum = 0, factor = 10;
- // Local class for local function.
- struct local_add : virtual_func::interface {
- explicit local_add(int& _sum, const int& _factor)
- : sum_(_sum), factor_(_factor) {}
- inline void operator()(const int& num) {
- body(sum_, factor_, num);
- }
- inline static void call(void* obj, const int& num) {
- local_add* self = static_cast<local_add*>(obj);
- self->body(self->sum_, self->factor_, num);
- }
- private:
- int& sum_;
- const int& factor_;
- inline void body(int& sum, const int& factor, const int& num) {
- sum += factor * num;
- }
- } add_local(sum, factor);
- casting_func add_casting(&add_local, &local_add::call);
- virtual_func add_virtual(add_local);
- std::vector<int> v(10);
- std::fill(v.begin(), v.end(), 1);
-
- // std::for_each(v.begin(), v.end(), add_local); // Error but OK on C++11.
- std::for_each(v.begin(), v.end(), add_casting); // OK.
- std::for_each(v.begin(), v.end(), add_virtual); // OK.
- BOOST_TEST(sum == 200);
- return boost::report_errors();
- }
- //]
|