blob: c8e49a9fb3bea8ca0e95ff56b42fd177d78329c3 [file] [log] [blame]
/*
* 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.
*/
#include <string>
#include <vector>
#include <boost/assign.hpp>
#include <boost/shared_ptr.hpp>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include "drill/collections.hpp"
#include "collectionsImpl.hpp"
namespace {
template<typename T, typename Iter>
class DrillVectorIteratorImpl: public Drill::impl::DrillIteratorImpl<T> {
public:
typedef DrillVectorIteratorImpl<T, Iter> type;
typedef Drill::impl::DrillIteratorImpl<T> supertype;
DrillVectorIteratorImpl(const Iter& it): m_it(it) {};
T& operator*() const { return m_it.operator *();}
T* operator->() const { return m_it.operator->(); }
operator typename Drill::impl::DrillIteratorImpl<const T>::iterator_ptr() const { return typename Drill::impl::DrillIteratorImpl<const T>::iterator_ptr(new DrillVectorIteratorImpl<const T, Iter>(m_it)); }
DrillVectorIteratorImpl& operator++() {
m_it++; return *this;
}
bool operator==(const supertype& x) const {
const type& other(dynamic_cast<const type&>(x));
return m_it == other.m_it;
}
bool operator!=(const supertype& x) const { return !(*this==x); }
private:
Iter m_it;
};
template<typename T>
class DrillVectorImpl: public Drill::impl::DrillCollectionImpl<T> {
public:
typedef Drill::impl::DrillCollectionImpl<T> supertype;
typedef typename supertype::iterator_ptr iterator_ptr;
typedef typename supertype::const_iterator_ptr const_iterator_ptr;
DrillVectorImpl() {}
DrillVectorImpl(const std::vector<T>& v): m_vector(v) {};
iterator_ptr begin() { return iterator_ptr(new IteratorImpl(m_vector.begin()));}
const_iterator_ptr begin() const { return const_iterator_ptr(new ConstIteratorImpl(m_vector.begin()));}
iterator_ptr end() { return iterator_ptr(new IteratorImpl(m_vector.end()));}
const_iterator_ptr end() const { return const_iterator_ptr(new ConstIteratorImpl(m_vector.end()));}
private:
typedef DrillVectorIteratorImpl<T, typename std::vector<T>::iterator> IteratorImpl;
typedef DrillVectorIteratorImpl<const T, typename std::vector<T>::const_iterator> ConstIteratorImpl;
std::vector<T> m_vector;
};
template<typename T>
class DrillVector: public Drill::DrillCollection<T> {
public:
DrillVector(const std::vector<T>& v): Drill::DrillCollection<T>(typename Drill::DrillCollection<T>::ImplPtr(new DrillVectorImpl<T>(v))) {}
};
struct SimpleInterface {
virtual ~SimpleInterface() {}
virtual const std::string& foo() const = 0;
virtual std::string bar() = 0;
};
class SimpleImplementation: public SimpleInterface {
public:
SimpleImplementation(const std::string& foo, const std::string& bar): m_foo(foo), m_bar(bar) {}
const std::string& foo() const { return m_foo; }
std::string bar() { return m_bar; }
private:
std::string m_foo;
std::string m_bar;
};
} // anonymous namespace
class CollectionsTest: public CppUnit::TestFixture {
public:
CollectionsTest() {}
CPPUNIT_TEST_SUITE( CollectionsTest );
CPPUNIT_TEST( testSimpleCollection );
CPPUNIT_TEST( testSimpleConstCollection );
CPPUNIT_TEST( testDrillVectorConstIterator );
CPPUNIT_TEST( testDrillVectorIterator );
CPPUNIT_TEST( testDrillVectorConstPointer );
CPPUNIT_TEST_SUITE_END();
void testSimpleCollection() {
// basic test/proof of concept for collections.hpp
std::vector<std::string> v = boost::assign::list_of("foo")("bar");
DrillVector<std::string> drillCollection(v);
std::vector<std::string> result;
for(DrillVector<std::string>::const_iterator it = drillCollection.begin(); it != drillCollection.end(); ++it) {
result.push_back(*it);
}
CPPUNIT_ASSERT(result == v);
}
void testSimpleConstCollection() {
std::vector<std::string> v = boost::assign::list_of("foo")("bar");
const DrillVector<std::string> drillCollection(v);
std::vector<std::string> result;
for(DrillVector<std::string>::const_iterator it = drillCollection.begin(); it != drillCollection.end(); ++it) {
result.push_back(*it);
}
CPPUNIT_ASSERT(result == v);
}
void testDrillVectorConstIterator() {
typedef Drill::DrillVector<SimpleInterface, SimpleImplementation> SimpleInterfaceVector;
SimpleInterfaceVector v;
v.push_back(SimpleImplementation("foo1", "bar1"));
v.push_back(SimpleImplementation("foo2", "bar2"));
std::vector<std::string> resultFoo;
SimpleInterfaceVector::const_iterator it(v.begin());
for(; it != v.end(); ++it) {
resultFoo.push_back(it->foo());
// const-correctness: The following line does not compile if uncommented!
// resultBar.push_back(it->bar());
}
std::vector<std::string> expectedFoo = boost::assign::list_of("foo1")("foo2");
CPPUNIT_ASSERT(resultFoo == expectedFoo);
}
void testDrillVectorIterator() {
typedef Drill::DrillVector<SimpleInterface, SimpleImplementation> SimpleInterfaceVector;
SimpleInterfaceVector v;
v.push_back(SimpleImplementation("foo1", "bar1"));
v.push_back(SimpleImplementation("foo2", "bar2"));
std::vector<std::string> resultFoo;
std::vector<std::string> resultBar;
SimpleInterfaceVector::iterator it;
for(it = v.begin(); it != v.end(); ++it) {
resultFoo.push_back(it->foo());
resultBar.push_back(it->bar());
}
std::vector<std::string> expectedFoo = boost::assign::list_of("foo1")("foo2");
std::vector<std::string> expectedBar = boost::assign::list_of("bar1")("bar2");
CPPUNIT_ASSERT(resultFoo == expectedFoo);
CPPUNIT_ASSERT(resultBar == expectedBar);
}
// Check some const-correctness issues
// by getting iterators of a const collection
void testDrillVectorConstPointer() {
typedef Drill::DrillVector<SimpleInterface, SimpleImplementation> SimpleInterfaceVector;
boost::shared_ptr<SimpleInterfaceVector> v(new SimpleInterfaceVector);
const SimpleInterfaceVector* vv(v.get());
v->push_back(SimpleImplementation("foo1", "bar1"));
v->push_back(SimpleImplementation("foo2", "bar2"));
std::vector<std::string> resultFoo;
std::vector<std::string> resultBar;
SimpleInterfaceVector::const_iterator it;
for(it = vv->begin(); it != vv->end(); ++it) {
resultFoo.push_back(it->foo());
}
std::vector<std::string> expectedFoo = boost::assign::list_of("foo1")("foo2");
CPPUNIT_ASSERT(resultFoo == expectedFoo);
}
};
CPPUNIT_TEST_SUITE_REGISTRATION( CollectionsTest );