blob: 980c5c947ed8a29aa964e162005f097f139297c7 [file] [log] [blame]
#ifndef _PRAGMA_COPYRIGHT_
#define _PRAGMA_COPYRIGHT_
#pragma comment(copyright, "%Z% %I% %W% %D% %T%\0")
#endif /* _PRAGMA_COPYRIGHT_ */
/****************************************************************************
* Copyright (c) 2008, 2010 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0s
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
Classes: Group
Description: Group manipulation.
Author: Hanhong Xue
History:
Date Who ID Description
-------- --- --- -----------
10/06/08 hxue Initial code (D153875)
****************************************************************************/
#include "group.hpp"
#include <assert.h>
#include <ctype.h>
#include <stdio.h>
Group::Group()
{
}
Group::Group(ClientId clientId)
{
Add(Range(clientId, clientId+1));
}
Group::Group(Range r)
{
Add(r);
}
Group::Group(Group &group)
{
Add(group);
}
bool Group::operator == (Group &g)
{
if (rangeList.size() != g.rangeList.size())
return false;
for (int i = 0; i < (int)rangeList.size(); i++)
if (rangeList[i] != g.rangeList[i])
return false;
return true;
}
bool Group::HasMember(ClientId clientId)
{
range_iterator it;
for (it=rangeList.begin(); it!=rangeList.end(); ++it) {
if (clientId >= (*it).end()) {
continue;
} else if (clientId >= (*it).begin()) {
return true;
}
}
return false;
}
bool Group::HasRange(Range & r)
{
for(Range::iterator i=r.begin(); i< r.end(); i++ )
if (this->HasMember(i))
continue;
else
return false;
return true;
}
int Group::Index(ClientId clientId)
{
int index = 0;
range_iterator it = rangeList.begin();
for ( ; it!=rangeList.end(); ++it) {
if (clientId < (*it).begin()) {
break;
} else if (clientId < (*it).end()) {
return index + clientId - (*it).begin();
} else {
index += (*it).end() - (*it).begin();
}
}
assert(!"Should have found index");
return index;
}
range_iterator Group::Add(ClientId clientId)
{
return Add(Range(clientId, clientId+1));
}
range_iterator Group::Add(Range r)
{
return Add(r, rangeList.begin());
}
range_iterator Group::Add(Range r, range_iterator range)
{
// shortcut for a higher range
if (!rangeList.empty() && !r.Touches(*rangeList.rbegin())
&& !r.IsBefore(*rangeList.rbegin()))
return rangeList.insert(rangeList.end(), r);
for (; range != rangeList.end(); range++)
if (r.Touches(*range) || r.IsBefore(*range))
break;
if (range == rangeList.end()) {
return rangeList.insert(range, r);
} else if (r.Touches(*range)) {
*range = r.Union(*range);
while (range + 1 != rangeList.end() && range->Touches(*(range+1))) {
*range = range->Union(*(range+1));
rangeList.erase(range+1);
}
return range;
} else {
return rangeList.insert(range, r);
}
}
void Group::Add(Group &group)
{
range_iterator pos = rangeList.begin();
range_iterator it = group.rangeList.begin();
for ( ; it!=group.rangeList.end(); ++it) {
pos = Add((*it), pos);
}
}
void Group::Delete(ClientId clientId)
{
Delete(Range(clientId, clientId+1));
}
void Group::Delete(Range r)
{
Delete(r, rangeList.begin());
}
range_iterator Group::Delete(Range r, range_iterator range)
{
for (; range != rangeList.end(); range++)
if (r.Intersects(*range) || r.IsBefore(*range))
break;
if (range == rangeList.end())
return range;
else if (r.Intersects(*range)) {
range_iterator savedRange = range;
if (r.Splits(*range)) {
Range newRange(r.end(), range->end());
*range = Range(range->begin(), r.begin());
range = rangeList.insert(range+1, newRange);
return range;
} else {
while (range != rangeList.end()) {
if (r.Contains(*range)) {
rangeList.erase(range);
} else {
*range = range->Difference(r);
range++;
}
}
}
return savedRange;
} else
return range;
}
void Group::Delete(Group &group)
{
range_iterator pos = rangeList.begin();
range_iterator it = group.rangeList.begin();
for ( ; it!=group.rangeList.end(); ++it) {
pos = Delete((*it), pos);
}
}
void Group::Clear()
{
rangeList.clear();
}
Group::iterator Group::begin()
{
return iterator(rangeList.begin(), rangeList.end());
}
Group::iterator Group::end()
{
return iterator(rangeList.end(), rangeList.end());
}
size_t Group::size()
{
int len = 0;
range_iterator it = rangeList.begin();
for ( ; it!=rangeList.end(); ++it) {
len += (*it).end() - (*it).begin();
}
return len;
}
/////////////////////////////////////////
Group::iterator::iterator(range_iterator first, range_iterator last)
: firstRange(first), lastRange(last)
{
if (firstRange != lastRange)
clientId = firstRange->begin();
else
clientId = -1;
}
ClientId & Group::iterator::operator *()
{
return clientId;
}
Group::iterator Group::iterator::operator ++ (int)
{
if (++clientId == firstRange->end()) {
firstRange++;
if (firstRange != lastRange)
clientId = firstRange->begin();
else
clientId = -1;
}
return *this;
}
bool Group::iterator::operator == (Group::iterator it)
{
return firstRange == it.firstRange && clientId == it.clientId;
}
bool Group::iterator::operator != (Group::iterator it)
{
return !(*this == it);
}