annotate DEPENDENCIES/generic/include/boost/signals2/detail/slot_groups.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 2665513ce2d3
children
rev   line source
Chris@16 1 // Boost.Signals2 library
Chris@16 2
Chris@16 3 // Copyright Frank Mori Hess 2007-2008.
Chris@16 4 // Use, modification and
Chris@16 5 // distribution is subject to the Boost Software License, Version
Chris@16 6 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 7 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8
Chris@16 9 // For more information, see http://www.boost.org
Chris@16 10
Chris@16 11 #ifndef BOOST_SIGNALS2_SLOT_GROUPS_HPP
Chris@16 12 #define BOOST_SIGNALS2_SLOT_GROUPS_HPP
Chris@16 13
Chris@16 14 #include <boost/signals2/connection.hpp>
Chris@16 15 #include <boost/optional.hpp>
Chris@16 16 #include <list>
Chris@16 17 #include <map>
Chris@16 18 #include <utility>
Chris@16 19
Chris@16 20 namespace boost {
Chris@16 21 namespace signals2 {
Chris@16 22 namespace detail {
Chris@16 23 enum slot_meta_group {front_ungrouped_slots, grouped_slots, back_ungrouped_slots};
Chris@16 24 template<typename Group>
Chris@16 25 struct group_key
Chris@16 26 {
Chris@16 27 typedef std::pair<enum slot_meta_group, boost::optional<Group> > type;
Chris@16 28 };
Chris@16 29 template<typename Group, typename GroupCompare>
Chris@16 30 class group_key_less
Chris@16 31 {
Chris@16 32 public:
Chris@16 33 group_key_less()
Chris@16 34 {}
Chris@16 35 group_key_less(const GroupCompare &group_compare): _group_compare(group_compare)
Chris@16 36 {}
Chris@16 37 bool operator ()(const typename group_key<Group>::type &key1, const typename group_key<Group>::type &key2) const
Chris@16 38 {
Chris@16 39 if(key1.first != key2.first) return key1.first < key2.first;
Chris@16 40 if(key1.first != grouped_slots) return false;
Chris@16 41 return _group_compare(key1.second.get(), key2.second.get());
Chris@16 42 }
Chris@16 43 private:
Chris@16 44 GroupCompare _group_compare;
Chris@16 45 };
Chris@16 46 template<typename Group, typename GroupCompare, typename ValueType>
Chris@16 47 class grouped_list
Chris@16 48 {
Chris@16 49 public:
Chris@16 50 typedef group_key_less<Group, GroupCompare> group_key_compare_type;
Chris@16 51 private:
Chris@16 52 typedef std::list<ValueType> list_type;
Chris@16 53 typedef std::map
Chris@16 54 <
Chris@16 55 typename group_key<Group>::type,
Chris@16 56 typename list_type::iterator,
Chris@16 57 group_key_compare_type
Chris@16 58 > map_type;
Chris@16 59 typedef typename map_type::iterator map_iterator;
Chris@16 60 typedef typename map_type::const_iterator const_map_iterator;
Chris@16 61 public:
Chris@16 62 typedef typename list_type::iterator iterator;
Chris@16 63 typedef typename list_type::const_iterator const_iterator;
Chris@16 64 typedef typename group_key<Group>::type group_key_type;
Chris@16 65
Chris@16 66 grouped_list(const group_key_compare_type &group_key_compare):
Chris@16 67 _group_key_compare(group_key_compare)
Chris@16 68 {}
Chris@16 69 grouped_list(const grouped_list &other): _list(other._list),
Chris@16 70 _group_map(other._group_map), _group_key_compare(other._group_key_compare)
Chris@16 71 {
Chris@16 72 // fix up _group_map
Chris@16 73 typename map_type::const_iterator other_map_it;
Chris@16 74 typename list_type::iterator this_list_it = _list.begin();
Chris@16 75 typename map_type::iterator this_map_it = _group_map.begin();
Chris@16 76 for(other_map_it = other._group_map.begin();
Chris@16 77 other_map_it != other._group_map.end();
Chris@16 78 ++other_map_it, ++this_map_it)
Chris@16 79 {
Chris@16 80 BOOST_ASSERT(this_map_it != _group_map.end());
Chris@16 81 this_map_it->second = this_list_it;
Chris@16 82 typename list_type::const_iterator other_list_it = other.get_list_iterator(other_map_it);
Chris@16 83 typename map_type::const_iterator other_next_map_it = other_map_it;
Chris@16 84 ++other_next_map_it;
Chris@16 85 typename list_type::const_iterator other_next_list_it = other.get_list_iterator(other_next_map_it);
Chris@16 86 while(other_list_it != other_next_list_it)
Chris@16 87 {
Chris@16 88 ++other_list_it;
Chris@16 89 ++this_list_it;
Chris@16 90 }
Chris@16 91 }
Chris@16 92 }
Chris@16 93 iterator begin()
Chris@16 94 {
Chris@16 95 return _list.begin();
Chris@16 96 }
Chris@16 97 iterator end()
Chris@16 98 {
Chris@16 99 return _list.end();
Chris@16 100 }
Chris@16 101 iterator lower_bound(const group_key_type &key)
Chris@16 102 {
Chris@16 103 map_iterator map_it = _group_map.lower_bound(key);
Chris@16 104 return get_list_iterator(map_it);
Chris@16 105 }
Chris@16 106 iterator upper_bound(const group_key_type &key)
Chris@16 107 {
Chris@16 108 map_iterator map_it = _group_map.upper_bound(key);
Chris@16 109 return get_list_iterator(map_it);
Chris@16 110 }
Chris@16 111 void push_front(const group_key_type &key, const ValueType &value)
Chris@16 112 {
Chris@16 113 map_iterator map_it;
Chris@16 114 if(key.first == front_ungrouped_slots)
Chris@16 115 {// optimization
Chris@16 116 map_it = _group_map.begin();
Chris@16 117 }else
Chris@16 118 {
Chris@16 119 map_it = _group_map.lower_bound(key);
Chris@16 120 }
Chris@16 121 m_insert(map_it, key, value);
Chris@16 122 }
Chris@16 123 void push_back(const group_key_type &key, const ValueType &value)
Chris@16 124 {
Chris@16 125 map_iterator map_it;
Chris@16 126 if(key.first == back_ungrouped_slots)
Chris@16 127 {// optimization
Chris@16 128 map_it = _group_map.end();
Chris@16 129 }else
Chris@16 130 {
Chris@16 131 map_it = _group_map.upper_bound(key);
Chris@16 132 }
Chris@16 133 m_insert(map_it, key, value);
Chris@16 134 }
Chris@16 135 void erase(const group_key_type &key)
Chris@16 136 {
Chris@16 137 map_iterator map_it = _group_map.lower_bound(key);
Chris@16 138 iterator begin_list_it = get_list_iterator(map_it);
Chris@16 139 iterator end_list_it = upper_bound(key);
Chris@16 140 if(begin_list_it != end_list_it)
Chris@16 141 {
Chris@16 142 _list.erase(begin_list_it, end_list_it);
Chris@16 143 _group_map.erase(map_it);
Chris@16 144 }
Chris@16 145 }
Chris@16 146 iterator erase(const group_key_type &key, const iterator &it)
Chris@16 147 {
Chris@16 148 BOOST_ASSERT(it != _list.end());
Chris@16 149 map_iterator map_it = _group_map.lower_bound(key);
Chris@16 150 BOOST_ASSERT(map_it != _group_map.end());
Chris@16 151 BOOST_ASSERT(weakly_equivalent(map_it->first, key));
Chris@16 152 if(map_it->second == it)
Chris@16 153 {
Chris@16 154 iterator next = it;
Chris@16 155 ++next;
Chris@16 156 // if next is in same group
Chris@16 157 if(next != upper_bound(key))
Chris@16 158 {
Chris@16 159 _group_map[key] = next;
Chris@16 160 }else
Chris@16 161 {
Chris@16 162 _group_map.erase(map_it);
Chris@16 163 }
Chris@16 164 }
Chris@16 165 return _list.erase(it);
Chris@16 166 }
Chris@16 167 void clear()
Chris@16 168 {
Chris@16 169 _list.clear();
Chris@16 170 _group_map.clear();
Chris@16 171 }
Chris@16 172 private:
Chris@16 173 /* Suppress default assignment operator, since it has the wrong semantics. */
Chris@16 174 grouped_list& operator=(const grouped_list &other);
Chris@16 175
Chris@16 176 bool weakly_equivalent(const group_key_type &arg1, const group_key_type &arg2)
Chris@16 177 {
Chris@16 178 if(_group_key_compare(arg1, arg2)) return false;
Chris@16 179 if(_group_key_compare(arg2, arg1)) return false;
Chris@16 180 return true;
Chris@16 181 }
Chris@16 182 void m_insert(const map_iterator &map_it, const group_key_type &key, const ValueType &value)
Chris@16 183 {
Chris@16 184 iterator list_it = get_list_iterator(map_it);
Chris@16 185 iterator new_it = _list.insert(list_it, value);
Chris@16 186 if(map_it != _group_map.end() && weakly_equivalent(key, map_it->first))
Chris@16 187 {
Chris@16 188 _group_map.erase(map_it);
Chris@16 189 }
Chris@16 190 map_iterator lower_bound_it = _group_map.lower_bound(key);
Chris@16 191 if(lower_bound_it == _group_map.end() ||
Chris@16 192 weakly_equivalent(lower_bound_it->first, key) == false)
Chris@16 193 {
Chris@16 194 /* doing the following instead of just
Chris@16 195 _group_map[key] = new_it;
Chris@16 196 to avoid bogus error when enabling checked iterators with g++ */
Chris@16 197 _group_map.insert(typename map_type::value_type(key, new_it));
Chris@16 198 }
Chris@16 199 }
Chris@16 200 iterator get_list_iterator(const const_map_iterator &map_it)
Chris@16 201 {
Chris@16 202 iterator list_it;
Chris@16 203 if(map_it == _group_map.end())
Chris@16 204 {
Chris@16 205 list_it = _list.end();
Chris@16 206 }else
Chris@16 207 {
Chris@16 208 list_it = map_it->second;
Chris@16 209 }
Chris@16 210 return list_it;
Chris@16 211 }
Chris@16 212 const_iterator get_list_iterator(const const_map_iterator &map_it) const
Chris@16 213 {
Chris@16 214 const_iterator list_it;
Chris@16 215 if(map_it == _group_map.end())
Chris@16 216 {
Chris@16 217 list_it = _list.end();
Chris@16 218 }else
Chris@16 219 {
Chris@16 220 list_it = map_it->second;
Chris@16 221 }
Chris@16 222 return list_it;
Chris@16 223 }
Chris@16 224
Chris@16 225 list_type _list;
Chris@16 226 // holds iterators to first list item in each group
Chris@16 227 map_type _group_map;
Chris@16 228 group_key_compare_type _group_key_compare;
Chris@16 229 };
Chris@16 230 } // end namespace detail
Chris@16 231 enum connect_position { at_back, at_front };
Chris@16 232 } // end namespace signals2
Chris@16 233 } // end namespace boost
Chris@16 234
Chris@16 235 #endif // BOOST_SIGNALS2_SLOT_GROUPS_HPP