blob: 5f9298c3b56e22460cd285dd80a033735e49b41e [file] [log] [blame]
// Boost.Bimap
//
// Copyright (c) 2006-2007 Matias Capeletto
//
// Distributed under 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)
#ifndef LIBS_BIMAP_TEST_BIMAP_TEST_HPP
#define LIBS_BIMAP_TEST_BIMAP_TEST_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
// std
#include <cassert>
#include <algorithm>
#include <boost/lambda/lambda.hpp>
template< class Container, class Data >
void test_container(Container & c, const Data & d)
{
assert( d.size() > 2 );
c.clear();
BOOST_CHECK( c.size() == 0 );
BOOST_CHECK( c.empty() );
c.insert( *d.begin() );
c.insert( ++d.begin(),d.end() );
BOOST_CHECK( c.size() == d.size() );
BOOST_CHECK( c.size() <= c.max_size() );
BOOST_CHECK( ! c.empty() );
c.erase( c.begin() );
BOOST_CHECK( c.size() == d.size() - 1 );
c.erase( c.begin(), c.end() );
BOOST_CHECK( c.empty() );
c.insert( *d.begin() );
BOOST_CHECK( c.size() == 1 );
c.insert( c.begin(), *(++d.begin()) );
BOOST_CHECK( c.size() == 2 );
BOOST_CHECK( c.begin() != c.end() );
}
template< class Container, class Data >
void test_sequence_container(Container & c, const Data & d)
{
assert( d.size() > 2 );
c.clear();
BOOST_CHECK( c.size() == 0 );
BOOST_CHECK( c.empty() );
c.push_front( * d.begin() );
c.push_back ( *(++d.begin()) );
BOOST_CHECK( c.front() == * c.begin() );
BOOST_CHECK( c.back () == *(++c.begin()) );
BOOST_CHECK( c.size() == 2 );
BOOST_CHECK( c.size() <= c.max_size() );
BOOST_CHECK( ! c.empty() );
c.erase( c.begin() );
BOOST_CHECK( c.size() == 1 );
c.insert( c.begin(), *(++d.begin()) );
c.erase( c.begin(), c.end() );
BOOST_CHECK( c.empty() );
c.push_front( *d.begin() );
BOOST_CHECK( c.size() == 1 );
BOOST_CHECK( c.begin() != c.end() );
}
template< class Container, class Data >
void test_associative_container(Container & c, const Data & d)
{
assert( d.size() > 2 );
c.clear();
c.insert(d.begin(),d.end());
for( typename Data::const_iterator di = d.begin(), de = d.end();
di != de; ++di )
{
BOOST_CHECK( c.find(*di) != c.end() );
}
typename Data::const_iterator da = d.begin();
typename Data::const_iterator db = ++d.begin();
c.erase(*da);
BOOST_CHECK( c.size() == d.size()-1 );
BOOST_CHECK( c.count(*da) == 0 );
BOOST_CHECK( c.count(*db) == 1 );
BOOST_CHECK( c.find(*da) == c.end() );
BOOST_CHECK( c.find(*db) != c.end() );
BOOST_CHECK( c.equal_range(*db).first != c.end() );
c.clear();
BOOST_CHECK( c.equal_range(*da).first == c.end() );
}
template< class Container, class Data >
void test_pair_associative_container(Container & c, const Data & d)
{
assert( d.size() > 2 );
c.clear();
c.insert(d.begin(),d.end());
for( typename Data::const_iterator di = d.begin(), de = d.end();
di != de; ++di )
{
BOOST_CHECK( c.find(di->first) != c.end() );
}
typename Data::const_iterator da = d.begin();
typename Data::const_iterator db = ++d.begin();
c.erase(da->first);
BOOST_CHECK( c.size() == d.size()-1 );
BOOST_CHECK( c.count(da->first) == 0 );
BOOST_CHECK( c.count(db->first) == 1 );
BOOST_CHECK( c.find(da->first) == c.end() );
BOOST_CHECK( c.find(db->first) != c.end() );
BOOST_CHECK( c.equal_range(db->first).first != c.end() );
c.clear();
BOOST_CHECK( c.equal_range(da->first).first == c.end() );
}
template< class Container, class Data >
void test_simple_ordered_associative_container_equality(Container & c, const Data & d)
{
BOOST_CHECK( std::equal( c. begin(), c. end(), d. begin() ) );
BOOST_CHECK( std::equal( c.rbegin(), c.rend(), d.rbegin() ) );
BOOST_CHECK( c.lower_bound( *d.begin() ) == c.begin() );
BOOST_CHECK( c.upper_bound( *d.begin() ) == ++c.begin() );
}
template< class Container, class Data >
void test_simple_ordered_associative_container(Container & c, const Data & d)
{
assert( d.size() > 2 );
c.clear();
c.insert(d.begin(),d.end());
for( typename Data::const_iterator di = d.begin(), de = d.end();
di != de; ++di )
{
typename Container::const_iterator ci = c.find(*di);
BOOST_CHECK( ci != c.end() );
BOOST_CHECK( ! c.key_comp()(*ci,*di) );
BOOST_CHECK( ! c.value_comp()(*ci,*di) );
}
test_simple_ordered_associative_container_equality(c, d);
const Container & cr = c;
test_simple_ordered_associative_container_equality(cr, d);
/*
BOOST_CHECK( c.range( *c.begin() <= ::boost::lambda::_1,
::boost::lambda::_1 <= *(++c.begin()) ).
first == c.begin()
);
*/
}
template< class Container, class Data >
void test_simple_unordered_associative_container(Container & c, const Data & d)
{
c.clear();
c.insert( d.begin(), d.end() );
BOOST_CHECK( c.bucket_count() * c.max_load_factor() >= d.size() );
BOOST_CHECK( c.max_bucket_count() >= c.bucket_count() );
for( typename Data::const_iterator di = d.begin(), de = d.end() ;
di != de ; ++di )
{
// non const
{
typename Container::size_type nb = c.bucket(*c.find(*di));
BOOST_CHECK( c.begin(nb) != c.end(nb) );
}
// const
{
const Container & const_c = c;
BOOST_CHECK(
const_c.bucket_size(const_c.bucket(*di)) == 1
);
typename Container::size_type nb =
const_c.bucket(*const_c.find(*di));
BOOST_CHECK(
const_c.begin(nb) != const_c.end(nb)
);
}
}
BOOST_CHECK( c.load_factor() < c.max_load_factor() );
c.max_load_factor(0.75);
BOOST_CHECK( c.max_load_factor() == 0.75 );
c.rehash(10);
}
template< class Container, class Data >
void test_pair_ordered_associative_container_equality(Container & c, const Data & d)
{
BOOST_CHECK( std::equal( c. begin(), c. end(), d. begin() ) );
BOOST_CHECK( std::equal( c.rbegin(), c.rend(), d.rbegin() ) );
BOOST_CHECK( c.lower_bound( d.begin()->first ) == c.begin() );
BOOST_CHECK( c.upper_bound( d.begin()->first ) == ++c.begin() );
}
template< class Container, class Data >
void test_pair_ordered_associative_container(Container & c, const Data & d)
{
assert( d.size() > 2 );
c.clear();
c.insert(d.begin(),d.end());
for( typename Container::const_iterator ci = c.begin(), ce = c.end();
ci != ce; ++ci )
{
typename Data::const_iterator di = d.find(ci->first);
BOOST_CHECK( di != d.end() );
BOOST_CHECK( ! c.key_comp()(di->first,ci->first) );
BOOST_CHECK( ! c.value_comp()(*ci,*di) );
}
test_pair_ordered_associative_container_equality(c, d);
const Container & cr = c;
test_pair_ordered_associative_container_equality(cr, d);
BOOST_CHECK( c.range( c.begin()->first <= ::boost::lambda::_1,
::boost::lambda::_1 <= (++c.begin())->first ).
first == c.begin()
);
}
template< class Container, class Data >
void test_pair_unordered_associative_container(Container & c, const Data & d)
{
c.clear();
c.insert( d.begin(), d.end() );
BOOST_CHECK( c.bucket_count() * c.max_load_factor() >= d.size() );
BOOST_CHECK( c.max_bucket_count() >= c.bucket_count() );
for( typename Data::const_iterator di = d.begin(), de = d.end() ;
di != de ; ++di )
{
// non const
{
typename Container::size_type nb =
c.bucket(c.find(di->first)->first);
BOOST_CHECK( c.begin(nb) != c.end(nb) );
}
// const
{
const Container & const_c = c;
BOOST_CHECK( const_c.bucket_size(const_c.bucket(di->first)) == 1 );
typename Container::size_type nb =
const_c.bucket(const_c.find(di->first)->first);
BOOST_CHECK( const_c.begin(nb) != const_c.end(nb) );
}
}
BOOST_CHECK( c.load_factor() < c.max_load_factor() );
c.max_load_factor(0.75);
BOOST_CHECK( c.max_load_factor() == 0.75 );
c.rehash(10);
}
template< class Container, class Data >
void test_unique_container(Container & c, Data & d)
{
c.clear();
c.insert(d.begin(),d.end());
c.insert(*d.begin());
BOOST_CHECK( c.size() == d.size() );
}
template< class Container, class Data >
void test_non_unique_container(Container & c, Data & d)
{
c.clear();
c.insert(d.begin(),d.end());
c.insert(*d.begin());
BOOST_CHECK( c.size() == (d.size()+1) );
}
template< class Bimap, class Data, class LeftData, class RightData >
void test_basic_bimap( Bimap & b,
const Data & d,
const LeftData & ld, const RightData & rd)
{
using namespace boost::bimaps;
test_container(b,d);
BOOST_CHECK( & b.left == & b.template by<member_at::left >() );
BOOST_CHECK( & b.right == & b.template by<member_at::right>() );
test_container(b.left , ld);
test_container(b.right, rd);
}
template< class LeftTag, class RightTag, class Bimap, class Data >
void test_tagged_bimap(Bimap & b,
const Data & d)
{
using namespace boost::bimaps;
BOOST_CHECK( &b.left == & b.template by<LeftTag >() );
BOOST_CHECK( &b.right == & b.template by<RightTag>() );
b.clear();
b.insert( *d.begin() );
BOOST_CHECK(
b.begin()->template get<LeftTag>() ==
b.template by<RightTag>().begin()->template get<LeftTag>()
);
BOOST_CHECK(
b.begin()->template get<RightTag>() ==
b.template by<LeftTag>().begin()->template get<RightTag>()
);
// const test
{
const Bimap & bc = b;
BOOST_CHECK( &bc.left == & bc.template by<LeftTag>() );
BOOST_CHECK( &bc.right == & bc.template by<RightTag>() );
BOOST_CHECK( bc.begin()->template get<LeftTag>() ==
bc.template by<RightTag>().begin()->template get<LeftTag>() );
BOOST_CHECK( bc.begin()->template get<RightTag>() ==
bc.template by<LeftTag>().begin()->template get<RightTag>() );
}
}
template< class Bimap, class Data, class LeftData, class RightData >
void test_set_set_bimap(Bimap & b,
const Data & d,
const LeftData & ld, const RightData & rd)
{
using namespace boost::bimaps;
test_basic_bimap(b,d,ld,rd);
test_associative_container(b,d);
test_simple_ordered_associative_container(b,d);
test_pair_associative_container(b.left, ld);
test_pair_ordered_associative_container(b.left, ld);
test_unique_container(b.left, ld);
test_pair_associative_container(b.right, rd);
test_pair_ordered_associative_container(b.right, rd);
test_unique_container(b.right, rd);
}
template< class Bimap, class Data, class LeftData, class RightData >
void test_multiset_multiset_bimap(Bimap & b,
const Data & d,
const LeftData & ld, const RightData & rd)
{
using namespace boost::bimaps;
test_basic_bimap(b,d,ld,rd);
test_associative_container(b,d);
test_simple_ordered_associative_container(b,d);
test_pair_associative_container(b.left, ld);
test_pair_ordered_associative_container(b.left, ld);
test_non_unique_container(b.left, ld);
test_pair_associative_container(b.right, rd);
test_pair_ordered_associative_container(b.right, rd);
test_non_unique_container(b.right, rd);
}
template< class Bimap, class Data, class LeftData, class RightData >
void test_unordered_set_unordered_multiset_bimap(Bimap & b,
const Data & d,
const LeftData & ld,
const RightData & rd)
{
using namespace boost::bimaps;
test_basic_bimap(b,d,ld,rd);
test_associative_container(b,d);
test_simple_unordered_associative_container(b,d);
test_pair_associative_container(b.left, ld);
test_pair_unordered_associative_container(b.left, ld);
test_unique_container(b.left, ld);
test_pair_associative_container(b.right, rd);
test_pair_unordered_associative_container(b.right, rd);
// Caution, this side is a non unique container, but the other side is a
// unique container so, the overall bimap is a unique one.
test_unique_container(b.right, rd);
}
#endif // LIBS_BIMAP_TEST_BIMAP_TEST_HPP