| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef _DECAF_UTIL_STLSET_H_ |
| #define _DECAF_UTIL_STLSET_H_ |
| |
| #include <set> |
| #include <vector> |
| #include <memory> |
| #include <decaf/util/NoSuchElementException.h> |
| #include <decaf/util/concurrent/Synchronizable.h> |
| #include <decaf/util/concurrent/Mutex.h> |
| #include <decaf/util/Iterator.h> |
| #include <decaf/util/AbstractSet.h> |
| |
| namespace decaf { |
| namespace util { |
| |
| /** |
| * Set template that wraps around a std::set to provide |
| * a more user-friendly interface and to provide common |
| * functions that do not exist in std::set. |
| */ |
| template <typename E> |
| class StlSet : public decaf::util::AbstractSet<E> { |
| private: |
| |
| std::set<E> values; |
| |
| private: |
| |
| class SetIterator : public Iterator<E> { |
| private: |
| |
| typename std::set<E>::iterator current; |
| typename std::set<E>::iterator previous; |
| typename std::set<E>* set; |
| |
| private: |
| |
| SetIterator(const SetIterator&); |
| SetIterator operator=(const SetIterator&); |
| |
| public: |
| |
| SetIterator(typename std::set<E>* set) : |
| Iterator<E>(), current(set->begin()), previous(set->begin()), set(set) { |
| } |
| |
| virtual ~SetIterator() {} |
| |
| virtual E next() { |
| if (this->current == set->end()) { |
| throw NoSuchElementException( |
| __FILE__, __LINE__, "Set::Iterator::next - No more elements to return"); |
| } |
| |
| this->previous = this->current; |
| return *(this->current++); |
| } |
| |
| virtual bool hasNext() const { |
| return (this->current != set->end()); |
| } |
| |
| virtual void remove() { |
| if (this->previous == set->end()) { |
| throw lang::exceptions::IllegalStateException( |
| __FILE__, __LINE__, "Set::Iterator::remove - Invalid State to call remove"); |
| } |
| |
| this->set->erase(this->previous); |
| this->previous = this->set->end(); |
| } |
| }; |
| |
| class ConstSetIterator : public Iterator<E> { |
| private: |
| |
| typename std::set<E>::const_iterator current; |
| typename std::set<E>::const_iterator previous; |
| const typename std::set<E>* set; |
| |
| private: |
| |
| ConstSetIterator(const ConstSetIterator&); |
| ConstSetIterator operator=(const ConstSetIterator&); |
| |
| public: |
| |
| ConstSetIterator(const typename std::set<E>* set) : |
| Iterator<E>(), current(set->begin()), previous(set->begin()), set(set) { |
| } |
| |
| virtual ~ConstSetIterator() {} |
| |
| virtual E next() { |
| if (this->current == set->end()) { |
| throw NoSuchElementException( |
| __FILE__, __LINE__, "Set::Iterator::next - No more elements to return"); |
| } |
| |
| this->previous = this->current; |
| return *(this->current++); |
| } |
| |
| virtual bool hasNext() const { |
| return (this->current != set->end()); |
| } |
| |
| virtual void remove() { |
| throw lang::exceptions::UnsupportedOperationException( |
| __FILE__, __LINE__, "Set::Iterator::remove - Not Valid on a Const Iterator"); |
| } |
| }; |
| |
| public: |
| |
| /** |
| * Default constructor - does nothing. |
| */ |
| StlSet() : AbstractSet<E>(), values() {} |
| |
| /** |
| * Copy constructor - copies the content of the given set into this one. |
| * @param source The source set. |
| */ |
| StlSet(const StlSet& source) : AbstractCollection<E>(), AbstractSet<E>(), values() { |
| copy(source); |
| } |
| |
| /** |
| * Copy constructor - copies the content of the given set into this one. |
| * @param source The source set. |
| */ |
| StlSet(const Collection<E>& source) : AbstractSet<E>(), values() { |
| AbstractSet<E>::copy(source); |
| } |
| |
| virtual ~StlSet() {} |
| |
| /** |
| * {@inheritDoc} |
| */ |
| Iterator<E>* iterator() { |
| return new SetIterator(&values); |
| } |
| Iterator<E>* iterator() const { |
| return new ConstSetIterator(&values); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| virtual bool equals(const Collection<E>& collection) const { |
| |
| const StlSet<E>* setptr = dynamic_cast<const StlSet<E>*>(&collection); |
| if (setptr == NULL) { |
| return AbstractSet<E>::equals(collection); |
| } |
| |
| return this->values == setptr->values; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| virtual void copy(const Collection<E>& collection) { |
| |
| const StlSet<E>* setptr = dynamic_cast<const StlSet<E>*>(&collection); |
| if (setptr == NULL) { |
| AbstractSet<E>::copy(collection); |
| return; |
| } |
| |
| this->values.clear(); |
| this->values = setptr->values; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| virtual void clear() { |
| values.clear(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| virtual bool contains(const E& value) const { |
| typename std::set<E>::const_iterator iter; |
| iter = values.find(value); |
| return iter != values.end(); |
| } |
| |
| /** |
| * @return if the set contains any element or not, TRUE or FALSE |
| */ |
| virtual bool isEmpty() const { |
| return values.empty(); |
| } |
| |
| /** |
| * @return The number of elements in this set. |
| */ |
| virtual int size() const { |
| return (int) values.size(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| virtual bool add(const E& value) { |
| return values.insert(value).second; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| virtual bool remove(const E& value) { |
| return values.erase(value) != 0; |
| } |
| |
| }; |
| |
| }} |
| |
| #endif /*_DECAF_UTIL_STLSET_H_*/ |