slot_call_iterator.hpp 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. // Boost.Signals library
  2. // Copyright Douglas Gregor 2001-2004. Use, modification and
  3. // distribution is subject to the Boost Software License, Version
  4. // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. // For more information, see http://www.boost.org
  7. #ifndef BOOST_SIGNALS_SLOT_CALL_ITERATOR
  8. #define BOOST_SIGNALS_SLOT_CALL_ITERATOR
  9. #include <memory>
  10. #include <boost/iterator/iterator_facade.hpp>
  11. #include <boost/smart_ptr.hpp>
  12. #include <boost/signals/detail/config.hpp>
  13. #include <boost/signals/connection.hpp>
  14. #include <boost/optional.hpp>
  15. #ifdef BOOST_HAS_ABI_HEADERS
  16. # include BOOST_ABI_PREFIX
  17. #endif
  18. namespace boost {
  19. namespace BOOST_SIGNALS_NAMESPACE {
  20. namespace detail {
  21. // Generates a slot call iterator. Essentially, this is an iterator that:
  22. // - skips over disconnected slots in the underlying list
  23. // - calls the connected slots when dereferenced
  24. // - caches the result of calling the slots
  25. template<typename Function, typename Iterator>
  26. class slot_call_iterator
  27. : public iterator_facade<slot_call_iterator<Function, Iterator>,
  28. typename Function::result_type,
  29. single_pass_traversal_tag,
  30. typename Function::result_type const&>
  31. {
  32. typedef iterator_facade<slot_call_iterator<Function, Iterator>,
  33. typename Function::result_type,
  34. single_pass_traversal_tag,
  35. typename Function::result_type const&>
  36. inherited;
  37. typedef typename Function::result_type result_type;
  38. friend class iterator_core_access;
  39. public:
  40. slot_call_iterator(Iterator iter_in, Iterator end_in, Function func,
  41. optional<result_type> &c)
  42. : iter(iter_in), end(end_in), f(func), cache(&c)
  43. {
  44. iter = std::find_if(iter, end, is_callable());
  45. }
  46. typename inherited::reference
  47. dereference() const
  48. {
  49. if (!cache->is_initialized()) {
  50. cache->reset(f(*iter));
  51. }
  52. return cache->get();
  53. }
  54. void increment()
  55. {
  56. iter = std::find_if(++iter, end, is_callable());
  57. cache->reset();
  58. }
  59. bool equal(const slot_call_iterator& other) const
  60. {
  61. iter = std::find_if(iter, end, is_callable());
  62. other.iter = std::find_if(other.iter, other.end,
  63. is_callable());
  64. return iter == other.iter;
  65. }
  66. private:
  67. mutable Iterator iter;
  68. Iterator end;
  69. Function f;
  70. optional<result_type>* cache;
  71. };
  72. } // end namespace detail
  73. } // end namespace BOOST_SIGNALS_NAMESPACE
  74. } // end namespace boost
  75. #ifdef BOOST_HAS_ABI_HEADERS
  76. # include BOOST_ABI_SUFFIX
  77. #endif
  78. #endif // BOOST_SIGNALS_SLOT_CALL_ITERATOR