annotate DEPENDENCIES/generic/include/boost/signals2/detail/slot_call_iterator.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 // Boost.Signals2 library
Chris@16 2
Chris@16 3 // Copyright Douglas Gregor 2001-2004.
Chris@16 4 // Copyright Frank Mori Hess 2007-2008.
Chris@16 5 // Use, modification and
Chris@16 6 // distribution is subject to the Boost Software License, Version
Chris@16 7 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 8 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 9
Chris@16 10 // For more information, see http://www.boost.org
Chris@16 11
Chris@16 12 #ifndef BOOST_SIGNALS2_SLOT_CALL_ITERATOR_HPP
Chris@16 13 #define BOOST_SIGNALS2_SLOT_CALL_ITERATOR_HPP
Chris@16 14
Chris@16 15 #include <boost/assert.hpp>
Chris@16 16 #include <boost/aligned_storage.hpp>
Chris@16 17 #include <boost/iterator/iterator_facade.hpp>
Chris@16 18 #include <boost/optional.hpp>
Chris@16 19 #include <boost/scoped_ptr.hpp>
Chris@16 20 #include <boost/signals2/connection.hpp>
Chris@16 21 #include <boost/signals2/slot_base.hpp>
Chris@16 22 #include <boost/signals2/detail/auto_buffer.hpp>
Chris@16 23 #include <boost/signals2/detail/unique_lock.hpp>
Chris@16 24 #include <boost/weak_ptr.hpp>
Chris@16 25
Chris@16 26 namespace boost {
Chris@16 27 namespace signals2 {
Chris@16 28 namespace detail {
Chris@16 29 template<typename ResultType, typename Function>
Chris@16 30 class slot_call_iterator_cache
Chris@16 31 {
Chris@16 32 public:
Chris@16 33 slot_call_iterator_cache(const Function &f_arg):
Chris@16 34 f(f_arg),
Chris@16 35 connected_slot_count(0),
Chris@16 36 disconnected_slot_count(0)
Chris@16 37 {}
Chris@16 38 optional<ResultType> result;
Chris@16 39 typedef auto_buffer<void_shared_ptr_variant, store_n_objects<10> > tracked_ptrs_type;
Chris@16 40 tracked_ptrs_type tracked_ptrs;
Chris@16 41 Function f;
Chris@16 42 unsigned connected_slot_count;
Chris@16 43 unsigned disconnected_slot_count;
Chris@16 44 };
Chris@16 45
Chris@16 46 // Generates a slot call iterator. Essentially, this is an iterator that:
Chris@16 47 // - skips over disconnected slots in the underlying list
Chris@16 48 // - calls the connected slots when dereferenced
Chris@16 49 // - caches the result of calling the slots
Chris@16 50 template<typename Function, typename Iterator, typename ConnectionBody>
Chris@16 51 class slot_call_iterator_t
Chris@16 52 : public boost::iterator_facade<slot_call_iterator_t<Function, Iterator, ConnectionBody>,
Chris@16 53 typename Function::result_type,
Chris@16 54 boost::single_pass_traversal_tag,
Chris@16 55 typename Function::result_type const&>
Chris@16 56 {
Chris@16 57 typedef boost::iterator_facade<slot_call_iterator_t<Function, Iterator, ConnectionBody>,
Chris@16 58 typename Function::result_type,
Chris@16 59 boost::single_pass_traversal_tag,
Chris@16 60 typename Function::result_type const&>
Chris@16 61 inherited;
Chris@16 62
Chris@16 63 typedef typename Function::result_type result_type;
Chris@16 64
Chris@16 65 friend class boost::iterator_core_access;
Chris@16 66
Chris@16 67 public:
Chris@16 68 slot_call_iterator_t(Iterator iter_in, Iterator end_in,
Chris@16 69 slot_call_iterator_cache<result_type, Function> &c):
Chris@16 70 iter(iter_in), end(end_in),
Chris@16 71 cache(&c), callable_iter(end_in)
Chris@16 72 {
Chris@16 73 lock_next_callable();
Chris@16 74 }
Chris@16 75
Chris@16 76 typename inherited::reference
Chris@16 77 dereference() const
Chris@16 78 {
Chris@16 79 if (!cache->result) {
Chris@16 80 try
Chris@16 81 {
Chris@16 82 cache->result.reset(cache->f(*iter));
Chris@16 83 }
Chris@16 84 catch(expired_slot &)
Chris@16 85 {
Chris@16 86 (*iter)->disconnect();
Chris@16 87 throw;
Chris@16 88 }
Chris@16 89 }
Chris@16 90 return cache->result.get();
Chris@16 91 }
Chris@16 92
Chris@16 93 void increment()
Chris@16 94 {
Chris@16 95 ++iter;
Chris@16 96 lock_next_callable();
Chris@16 97 cache->result.reset();
Chris@16 98 }
Chris@16 99
Chris@16 100 bool equal(const slot_call_iterator_t& other) const
Chris@16 101 {
Chris@16 102 return iter == other.iter;
Chris@16 103 }
Chris@16 104
Chris@16 105 private:
Chris@16 106 typedef unique_lock<connection_body_base> lock_type;
Chris@16 107
Chris@16 108 void lock_next_callable() const
Chris@16 109 {
Chris@16 110 if(iter == callable_iter)
Chris@16 111 {
Chris@16 112 return;
Chris@16 113 }
Chris@16 114 for(;iter != end; ++iter)
Chris@16 115 {
Chris@101 116 cache->tracked_ptrs.clear();
Chris@16 117 lock_type lock(**iter);
Chris@16 118 (*iter)->nolock_grab_tracked_objects(std::back_inserter(cache->tracked_ptrs));
Chris@16 119 if((*iter)->nolock_nograb_connected())
Chris@16 120 {
Chris@16 121 ++cache->connected_slot_count;
Chris@16 122 }else
Chris@16 123 {
Chris@16 124 ++cache->disconnected_slot_count;
Chris@16 125 }
Chris@16 126 if((*iter)->nolock_nograb_blocked() == false)
Chris@16 127 {
Chris@16 128 callable_iter = iter;
Chris@16 129 break;
Chris@16 130 }
Chris@16 131 }
Chris@16 132 if(iter == end)
Chris@16 133 {
Chris@16 134 callable_iter = end;
Chris@16 135 }
Chris@16 136 }
Chris@16 137
Chris@16 138 mutable Iterator iter;
Chris@16 139 Iterator end;
Chris@16 140 slot_call_iterator_cache<result_type, Function> *cache;
Chris@16 141 mutable Iterator callable_iter;
Chris@16 142 };
Chris@16 143 } // end namespace detail
Chris@16 144 } // end namespace BOOST_SIGNALS_NAMESPACE
Chris@16 145 } // end namespace boost
Chris@16 146
Chris@16 147 #endif // BOOST_SIGNALS2_SLOT_CALL_ITERATOR_HPP