]> git.lyx.org Git - lyx.git/blob - boost/libs/signals/src/named_slot_map.cpp
scons-based build system, by Bo Peng (ben.bob@gmail.com)
[lyx.git] / boost / libs / signals / src / named_slot_map.cpp
1 // Boost.Signals library
2
3 // Copyright Douglas Gregor 2001-2004. Use, modification and
4 // distribution is subject to the Boost Software License, Version
5 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7
8 // For more information, see http://www.boost.org
9
10 #define BOOST_SIGNALS_SOURCE
11
12 #include <boost/signals/detail/named_slot_map.hpp>
13 #include <cassert>
14 #include <map>
15 #include <list>
16 #include <typeinfo>
17
18 namespace boost { namespace BOOST_SIGNALS_NAMESPACE { namespace detail {
19
20 typedef std::list<connection_slot_pair> group_list;
21 typedef group_list::iterator slot_pair_iterator;
22 typedef std::map<stored_group, group_list, compare_type> slot_container_type;
23 typedef slot_container_type::iterator group_iterator;
24 typedef slot_container_type::const_iterator const_group_iterator;
25
26 named_slot_map_iterator::named_slot_map_iterator() : slot_assigned(false) {}
27
28 named_slot_map_iterator::
29 named_slot_map_iterator(const named_slot_map_iterator& other)
30   : group(other.group), last_group(other.last_group),
31     slot_assigned(other.slot_assigned)
32 {
33   if (slot_assigned) slot_ = other.slot_;
34 }
35
36 named_slot_map_iterator&
37 named_slot_map_iterator::operator=(const named_slot_map_iterator& other)
38 {
39   slot_assigned = other.slot_assigned;
40   group = other.group;
41   last_group = other.last_group;
42   if (slot_assigned) slot_ = other.slot_;
43   return *this;
44 }
45
46
47 connection_slot_pair& named_slot_map_iterator::dereference() const
48 { return *slot_; }
49
50 void named_slot_map_iterator::increment()
51 {
52   ++slot_;
53   if (slot_ == group->second.end()) {
54     ++group;
55     init_next_group();
56   }
57 }
58
59 bool
60 named_slot_map_iterator::equal(const named_slot_map_iterator& other) const
61 {
62   return (group == other.group
63           && (group == last_group
64               || slot_ == other.slot_));
65 }
66
67 #if BOOST_WORKAROUND(_MSC_VER, <= 1400)
68 void named_slot_map_iterator::decrement() { assert(false); }
69 void named_slot_map_iterator::advance(difference_type) { assert(false); }
70 #endif
71
72 named_slot_map::named_slot_map(const compare_type& compare) : groups(compare)
73 {
74   clear();
75 }
76
77 void named_slot_map::clear()
78 {
79   groups.clear();
80   groups[stored_group(stored_group::sk_front)];
81   groups[stored_group(stored_group::sk_back)];
82   back = groups.end();
83   --back;
84 }
85
86 named_slot_map::iterator named_slot_map::begin()
87 {
88   return named_slot_map::iterator(groups.begin(), groups.end());
89 }
90
91 named_slot_map::iterator named_slot_map::end()
92 {
93   return named_slot_map::iterator(groups.end(), groups.end());
94 }
95
96 named_slot_map::iterator
97 named_slot_map::insert(const stored_group& name, const connection& con,
98                        const any& slot, connect_position at)
99 {
100   group_iterator group;
101   if (name.empty()) {
102     switch (at) {
103     case at_front: group = groups.begin(); break;
104     case at_back: group = back; break;
105     }
106   } else {
107     group = groups.find(name);
108     if (group == groups.end()) {
109       slot_container_type::value_type v(name, group_list());
110       group = groups.insert(v).first;
111     }
112   }
113   iterator it;
114   it.group = group;
115   it.last_group = groups.end();
116
117   switch (at) {
118   case at_back:
119     group->second.push_back(connection_slot_pair(con, slot));
120     it.slot_ = group->second.end();
121     it.slot_assigned = true;
122     --(it.slot_);
123     break;
124
125   case at_front:
126     group->second.push_front(connection_slot_pair(con, slot));
127     it.slot_ = group->second.begin();
128     it.slot_assigned = true;
129     break;
130   }
131   return it;
132 }
133
134 void named_slot_map::disconnect(const stored_group& name)
135 {
136   group_iterator group = groups.find(name);
137   if (group != groups.end()) {
138     slot_pair_iterator i = group->second.begin();
139     while (i != group->second.end()) {
140       slot_pair_iterator next = i;
141       ++next;
142       i->first.disconnect();
143       i = next;
144     }
145     groups.erase(group);
146   }
147 }
148
149 void named_slot_map::erase(iterator pos)
150 {
151   // Erase the slot
152   pos.slot_->first.disconnect();
153   pos.group->second.erase(pos.slot_);
154 }
155
156 void named_slot_map::remove_disconnected_slots()
157 {
158   // Remove any disconnected slots
159   group_iterator g = groups.begin();
160   while (g != groups.end()) {
161     slot_pair_iterator s = g->second.begin();
162     while (s != g->second.end()) {
163       if (s->first.connected()) ++s;
164       else g->second.erase(s++);
165     }
166
167     // Clear out empty groups
168     if (empty(g)) groups.erase(g++);
169     else ++g;
170   }
171 }
172
173
174 } } }