impl_tparam_tricks.cpp 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // Copyright (C) 2009-2012 Lorenzo Caminiti
  2. // Distributed under the Boost Software License, Version 1.0
  3. // (see accompanying file LICENSE_1_0.txt or a copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. // Home at http://www.boost.org/libs/local_function
  6. //[impl_tparam_tricks
  7. #include <boost/detail/lightweight_test.hpp>
  8. #include <vector>
  9. #include <algorithm>
  10. // Casting functor trick.
  11. struct casting_func {
  12. explicit casting_func(void* obj, void (*call)(void*, const int&))
  13. : obj_(obj), call_(call) {}
  14. // Unfortunately, function pointer call is not inlined.
  15. inline void operator()(const int& num) { call_(obj_, num); }
  16. private:
  17. void* obj_;
  18. void (*call_)(void*, const int&);
  19. };
  20. // Virtual functor trick.
  21. struct virtual_func {
  22. struct interface {
  23. // Unfortunately, virtual function call is not inlined.
  24. inline virtual void operator()(const int&) {}
  25. };
  26. explicit virtual_func(interface& func): func_(&func) {}
  27. inline void operator()(const int& num) { (*func_)(num); }
  28. private:
  29. interface* func_;
  30. };
  31. int main(void) {
  32. int sum = 0, factor = 10;
  33. // Local class for local function.
  34. struct local_add : virtual_func::interface {
  35. explicit local_add(int& _sum, const int& _factor)
  36. : sum_(_sum), factor_(_factor) {}
  37. inline void operator()(const int& num) {
  38. body(sum_, factor_, num);
  39. }
  40. inline static void call(void* obj, const int& num) {
  41. local_add* self = static_cast<local_add*>(obj);
  42. self->body(self->sum_, self->factor_, num);
  43. }
  44. private:
  45. int& sum_;
  46. const int& factor_;
  47. inline void body(int& sum, const int& factor, const int& num) {
  48. sum += factor * num;
  49. }
  50. } add_local(sum, factor);
  51. casting_func add_casting(&add_local, &local_add::call);
  52. virtual_func add_virtual(add_local);
  53. std::vector<int> v(10);
  54. std::fill(v.begin(), v.end(), 1);
  55. // std::for_each(v.begin(), v.end(), add_local); // Error but OK on C++11.
  56. std::for_each(v.begin(), v.end(), add_casting); // OK.
  57. std::for_each(v.begin(), v.end(), add_virtual); // OK.
  58. BOOST_TEST(sum == 200);
  59. return boost::report_errors();
  60. }
  61. //]