fork download
  1. #include <iostream>
  2. #include <iterator>
  3. #include <type_traits>
  4.  
  5.  
  6.  
  7. template<typename Fn>
  8. struct CallRepeatedlyIterator
  9. {
  10. using difference_type = unsigned;
  11. using value_type = typename std::result_of<Fn()>::type;
  12. using pointer = value_type *;
  13. using reference = value_type &;
  14. using iterator_category = std::input_iterator_tag;
  15.  
  16. bool is_end;
  17. union {
  18. Fn fn;
  19. };
  20. union {
  21. value_type buffer;
  22. };
  23.  
  24. value_type operator*() const
  25. {
  26. return buffer;
  27. }
  28.  
  29. CallRepeatedlyIterator & operator++()
  30. {
  31. buffer = fn();
  32. return *this;
  33. }
  34.  
  35. CallRepeatedlyIterator()
  36. : is_end(true)
  37. {}
  38.  
  39. explicit CallRepeatedlyIterator(Fn f)
  40. : is_end(false)
  41. {
  42. new (&fn) Fn(f);
  43. new (&buffer) value_type(fn());
  44. }
  45.  
  46. bool operator==(CallRepeatedlyIterator const & other) const
  47. {
  48. return is_end && other.is_end;
  49. }
  50.  
  51. bool operator!=(CallRepeatedlyIterator const & other) const
  52. {
  53. return !(*this == other);
  54. }
  55. };
  56.  
  57.  
  58. int foo()
  59. {
  60. static int i = 42;
  61. std::cerr << "foo() called" << std::endl;
  62. return ++i;
  63. }
  64.  
  65.  
  66. int main() {
  67. using fn_type = decltype(foo);
  68. CallRepeatedlyIterator<fn_type *> it(foo);
  69. CallRepeatedlyIterator<fn_type *> the_end;
  70. int calls = 4;
  71. for (; it != the_end; ++it)
  72. {
  73. std::cout << *it << std::endl;
  74. if (! (--calls)) break;
  75. }
  76. }
Success #stdin #stdout #stderr 0s 4504KB
stdin
Standard input is empty
stdout
43
44
45
46
stderr
foo() called
foo() called
foo() called
foo() called