blob: 1ddde63d8d9475b1c5c4c1b5e82c18f130543528 [file] [log] [blame]
// Boost.Signals library
// Copyright Douglas Gregor 2001-2004. Use, modification and
// distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// For more information, see http://www.boost.org
#define BOOST_SIGNALS_SOURCE
#include <boost/signals/detail/named_slot_map.hpp>
#include <cassert>
#include <map>
#include <list>
#include <typeinfo>
namespace boost { namespace BOOST_SIGNALS_NAMESPACE { namespace detail {
typedef std::list<connection_slot_pair> group_list;
typedef group_list::iterator slot_pair_iterator;
typedef std::map<stored_group, group_list, compare_type> slot_container_type;
typedef slot_container_type::iterator group_iterator;
typedef slot_container_type::const_iterator const_group_iterator;
#if BOOST_WORKAROUND(_MSC_VER, <= 1600)
void named_slot_map_iterator::decrement() { assert(false); }
void named_slot_map_iterator::advance(difference_type) { assert(false); }
#endif
named_slot_map::named_slot_map(const compare_type& compare) : groups(compare)
{
clear();
}
void named_slot_map::clear()
{
groups.clear();
groups[stored_group(stored_group::sk_front)];
groups[stored_group(stored_group::sk_back)];
back = groups.end();
--back;
}
named_slot_map::iterator named_slot_map::begin()
{
return named_slot_map::iterator(groups.begin(), groups.end());
}
named_slot_map::iterator named_slot_map::end()
{
return named_slot_map::iterator(groups.end(), groups.end());
}
named_slot_map::iterator
named_slot_map::insert(const stored_group& name, const connection& con,
const any& slot, connect_position at)
{
group_iterator group;
if (name.empty()) {
switch (at) {
case at_front: group = groups.begin(); break;
case at_back: group = back; break;
}
} else {
group = groups.find(name);
if (group == groups.end()) {
slot_container_type::value_type v(name, group_list());
group = groups.insert(v).first;
}
}
iterator it;
it.group = group;
it.last_group = groups.end();
switch (at) {
case at_back:
group->second.push_back(connection_slot_pair(con, slot));
it.slot_ = group->second.end();
it.slot_assigned = true;
--(it.slot_);
break;
case at_front:
group->second.push_front(connection_slot_pair(con, slot));
it.slot_ = group->second.begin();
it.slot_assigned = true;
break;
}
return it;
}
void named_slot_map::disconnect(const stored_group& name)
{
group_iterator group = groups.find(name);
if (group != groups.end()) {
slot_pair_iterator i = group->second.begin();
while (i != group->second.end()) {
slot_pair_iterator next = i;
++next;
i->first.disconnect();
i = next;
}
groups.erase(group);
}
}
void named_slot_map::erase(iterator pos)
{
// Erase the slot
pos.slot_->first.disconnect();
pos.group->second.erase(pos.slot_);
}
void named_slot_map::remove_disconnected_slots()
{
// Remove any disconnected slots
group_iterator g = groups.begin();
while (g != groups.end()) {
slot_pair_iterator s = g->second.begin();
while (s != g->second.end()) {
if (s->first.connected()) ++s;
else g->second.erase(s++);
}
// Clear out empty groups
if (empty(g)) groups.erase(g++);
else ++g;
}
}
} } }