// Boost.Range library
//
//  Copyright Thorsten Ottosen 2006. 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/libs/range/
//

#include <boost/range/adaptors.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/foreach.hpp>
#include <boost/assign/list_of.hpp>
#include <vector>
#include <list>
#include <string>
#include <map>

template< class T >
struct less_than
{
    T val;

    less_than() : val(0)
    {}
    
    less_than( T t ) : val(t)
    {}

    bool operator()( const T& r ) const
    {
        return r < val;
    }
};



template< class T >
struct multiply
{
    T val;
    
    typedef T& result_type;

    multiply( T t ) : val(t)
    { }
    
    T& operator()( T& r ) const
    {
        return r *= 2;
    }
};



template< class Rng >
void check_copy( Rng r )
{
    //
    // Make sure the generated iterators
    // can actually be copied
    //
    Rng r2 = r;
    r2     = r;
}



template< class Rng >
void check()
{
    using namespace boost::adaptors;
    
    Rng rng = boost::assign::list_of(1)(2)(3)(4)(5).to_container( rng );
    Rng out;

    //
    // test each alphabetically
    //
    BOOST_FOREACH( int i, rng | filtered( less_than<int>(4) ) 
                              /*| reversed*/ 
                              | transformed( multiply<int>(2) ) )
    {
      out.push_back( i );
    }

    BOOST_CHECK_EQUAL( out.size(), 3u );
    BOOST_CHECK_EQUAL( *out.begin(), 2 );
    BOOST_CHECK_EQUAL( *boost::next(out.begin()), 4 );
    BOOST_CHECK_EQUAL( *boost::next(out.begin(),2), 6 );

    rng = boost::assign::list_of(1)(1)(2)(2)(3)(3)(4)(5).to_container( rng );
    out.clear();
    /*
    BOOST_FOREACH( int i, rng | adjacent_filtered( std::equal_to<int>() )
                              | uniqued )
    {
        
        out.push_back( i );
    }*/
    
}



template< class IndirectRng >
void check_indirect()
{
    using namespace boost::adaptors;

    IndirectRng rng;

    std::vector< boost::shared_ptr< int > > holder;
    
    for( unsigned i = 0u; i != 20u; ++i )
    {
        boost::shared_ptr<int> v(new int(i));
        rng.push_back( v.get() );
    }

    BOOST_FOREACH( int& i, rng | indirected | reversed 
                               | transformed( multiply<int>(2) ) )
    {
        i += 1;
    }

    
    
}



template< class RandomAccessRng >
void check_random_access()
{
    using namespace boost::adaptors;
    
    RandomAccessRng rng(1, 20u);
    RandomAccessRng out;

    BOOST_FOREACH( int i, rng | reversed 
                              | transformed( multiply<int>(2) )  
                              /* | sliced(0,15) */ )
    {
      out.push_back( i );
    }

    
    BOOST_FOREACH( int i, rng | copied(3u,13u) )
    {
        out.push_back( i );
    }     
}



template< class Map >
void check_map()
{
    using namespace boost::adaptors;
    
    Map m;
    m.insert( std::make_pair(1,2) );
    m.insert( std::make_pair(2,2) );
    m.insert( std::make_pair(3,2) );
    m.insert( std::make_pair(4,2) );
    m.insert( std::make_pair(5,2) );
    m.insert( std::make_pair(6,2) );
    m.insert( std::make_pair(7,2) );

    std::vector<int> keys 
        = boost::copy_range< std::vector<int> >( m | map_keys );
    std::vector<int> values 
       = boost::copy_range< std::vector<int> >( m | map_values );
}



void check_regex()
{
    using namespace boost::adaptors;
    std::string s("This is a string of tokens");
    std::vector<std::string> tokens =
        boost::copy_range< std::vector<std::string> >( s | tokenized( "\\s+", -1 ) );
}


void check_adaptors()
{
    check< std::vector<int> >();
    check< std::list<int> >();
    check_indirect< std::vector<int*> >();
    check_indirect< std::list<int*> >();

    check_map< std::map<int,int> >();
//    check_random_access< std::vector<int> >();
    check_regex();

    using namespace boost::adaptors;
    std::vector<int>  vec(10u,20);
    std::vector<int*> pvec;
    std::map<int,int> map;
    
    check_copy( vec | adjacent_filtered( std::equal_to<int>() ) );
  //  check_copy( vec | indexed );
    check_copy( vec | reversed );
    check_copy( vec | uniqued );
    check_copy( pvec | indirected );

//    check_copy( vec | sliced(1,5) );
    //
    // This does not return an iterator_range<>, so
    // won't pass this test of implicit conversion
    //  check_copy( vec | copied(1,5) );
    //
    check_copy( map | map_values );
    check_copy( map | map_keys );
    check_copy( std::string( "a string" ) | tokenized( "\\s+", -1 ) );
    check_copy( vec | filtered( less_than<int>(2) ) );
    check_copy( vec | transformed( multiply<int>(2) ) ); 
}

using boost::unit_test::test_suite;

test_suite* init_unit_test_suite( int argc, char* argv[] )
{
    using namespace boost;

    test_suite* test = BOOST_TEST_SUITE( "Range Test Suite - Adaptors" );

    test->add( BOOST_TEST_CASE( &check_adaptors ) );

    return test;
}


