//
// Boost.Pointer Container
//
//  Copyright Thorsten Ottosen 2003-2005. 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/ptr_container/
//

#ifndef BOOST_PTR_CONTAINER_PTR_SET_ADAPTER_HPP
#define BOOST_PTR_CONTAINER_PTR_SET_ADAPTER_HPP

#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif

#include <boost/ptr_container/detail/associative_ptr_container.hpp>
#include <boost/ptr_container/detail/meta_functions.hpp>
#include <boost/ptr_container/detail/void_ptr_iterator.hpp>
#include <boost/range/iterator_range.hpp>

namespace boost
{
namespace ptr_container_detail
{
    template
    < 
        class Key,
        class VoidPtrSet,
        bool  Ordered
    >
    struct set_config
    {
       typedef VoidPtrSet 
                    void_container_type;

       typedef BOOST_DEDUCED_TYPENAME VoidPtrSet::allocator_type 
                    allocator_type;

       typedef Key  value_type;

       typedef value_type 
                    key_type;

       typedef BOOST_DEDUCED_TYPENAME 
           mpl::eval_if_c<Ordered, 
                          select_value_compare<VoidPtrSet>, 
                          mpl::identity<void> >::type
                    value_compare;

       typedef value_compare 
                    key_compare;

       typedef BOOST_DEDUCED_TYPENAME 
           mpl::eval_if_c<Ordered,
                          mpl::identity<void>,
                          select_hasher<VoidPtrSet> >::type
                    hasher;

       typedef BOOST_DEDUCED_TYPENAME 
           mpl::eval_if_c<Ordered,
                          mpl::identity<void>,
                          select_key_equal<VoidPtrSet> >::type
                    key_equal;

       typedef BOOST_DEDUCED_TYPENAME 
           mpl::if_c<Ordered,
                     ordered_associative_container_tag,
                     unordered_associative_container_tag>::type
                    container_type;

       typedef void_ptr_iterator<
                       BOOST_DEDUCED_TYPENAME VoidPtrSet::iterator, Key > 
                    iterator;

       typedef void_ptr_iterator<
                        BOOST_DEDUCED_TYPENAME VoidPtrSet::const_iterator, const Key >
                    const_iterator;

       typedef void_ptr_iterator<
           BOOST_DEDUCED_TYPENAME 
             mpl::eval_if_c<Ordered, 
                            select_iterator<VoidPtrSet>,
                            select_local_iterator<VoidPtrSet> >::type,
             Key >
                    local_iterator;

       typedef void_ptr_iterator<
           BOOST_DEDUCED_TYPENAME 
             mpl::eval_if_c<Ordered, 
                            select_iterator<VoidPtrSet>,
                            select_const_local_iterator<VoidPtrSet> >::type,
             const Key >
                    const_local_iterator;           
       
       template< class Iter >
       static Key* get_pointer( Iter i )
       {
           return static_cast<Key*>( *i.base() );
       }

       template< class Iter >
       static const Key* get_const_pointer( Iter i )
       {
           return static_cast<const Key*>( *i.base() );
       }

       BOOST_STATIC_CONSTANT(bool, allow_null = false );
    };

 
    
    template
    < 
        class Key,
        class VoidPtrSet, 
        class CloneAllocator = heap_clone_allocator,
        bool  Ordered        = true
    >
    class ptr_set_adapter_base 
        : public ptr_container_detail::associative_ptr_container< set_config<Key,VoidPtrSet,Ordered>,
                                                      CloneAllocator >
    {
        typedef ptr_container_detail::associative_ptr_container< set_config<Key,VoidPtrSet,Ordered>,
                                                     CloneAllocator >
              base_type;
    public:  
        typedef BOOST_DEDUCED_TYPENAME base_type::iterator 
                      iterator;
        typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator 
                      const_iterator;
        typedef Key   key_type;
        typedef BOOST_DEDUCED_TYPENAME base_type::size_type
                      size_type;

    public:
        ptr_set_adapter_base() 
        { }

        template< class SizeType >
        ptr_set_adapter_base( SizeType n, 
                              ptr_container_detail::unordered_associative_container_tag tag )
          : base_type( n, tag )
        { }
                
        template< class Compare, class Allocator >
        ptr_set_adapter_base( const Compare& comp,
                              const Allocator& a ) 
         : base_type( comp, a ) 
        { }

        template< class Hash, class Pred, class Allocator >
        ptr_set_adapter_base( const Hash& hash,
                              const Pred& pred,
                              const Allocator& a )
         : base_type( hash, pred, a )
        { }

        template< class InputIterator, class Compare, class Allocator >
        ptr_set_adapter_base( InputIterator first, InputIterator last,
                              const Compare& comp,
                              const Allocator& a ) 
         : base_type( first, last, comp, a ) 
        { }

        template< class InputIterator, class Hash, class Pred, class Allocator >
        ptr_set_adapter_base( InputIterator first, InputIterator last,
                              const Hash& hash,
                              const Pred& pred,
                              const Allocator& a )
         : base_type( first, last, hash, pred, a )
        { }
               
        template< class U, class Set, class CA, bool b >
        ptr_set_adapter_base( const ptr_set_adapter_base<U,Set,CA,b>& r )
          : base_type( r )
        { }

        ptr_set_adapter_base( const ptr_set_adapter_base& r )
          : base_type( r )
        { }
                
        template< class PtrContainer >
        explicit ptr_set_adapter_base( std::auto_ptr<PtrContainer> clone )
         : base_type( clone )
        { }
        
        ptr_set_adapter_base& operator=( ptr_set_adapter_base r ) 
        {
            this->swap( r );
            return *this;
        }
        
        template< typename PtrContainer >
        ptr_set_adapter_base& operator=( std::auto_ptr<PtrContainer> clone )    
        {
            base_type::operator=( clone );
            return *this;
        }

        using base_type::erase;
        
        size_type erase( const key_type& x ) // nothrow
        {
            key_type* key = const_cast<key_type*>(&x);
            iterator i( this->base().find( key ) );       
            if( i == this->end() )                                  // nothrow
                return 0u;                                          // nothrow
            key = static_cast<key_type*>(*i.base());                // nothrow
            size_type res = this->base().erase( key );              // nothrow 
            this->remove( key );                                    // nothrow
            return res;
        }


        iterator find( const key_type& x )                                                
        {                                                                            
            return iterator( this->base().
                             find( const_cast<key_type*>(&x) ) );            
        }                                                                            

        const_iterator find( const key_type& x ) const                                    
        {                                                                            
            return const_iterator( this->base().
                                   find( const_cast<key_type*>(&x) ) );                  
        }                                                                            

        size_type count( const key_type& x ) const                                        
        {                                                                            
            return this->base().count( const_cast<key_type*>(&x) );                      
        }                                                                            
                                                                                     
        iterator lower_bound( const key_type& x )                                         
        {                                                                            
            return iterator( this->base().
                             lower_bound( const_cast<key_type*>(&x) ) );                   
        }                                                                            
                                                                                     
        const_iterator lower_bound( const key_type& x ) const                             
        {                                                                            
            return const_iterator( this->base().
                                   lower_bound( const_cast<key_type*>(&x) ) );       
        }                                                                            
                                                                                     
        iterator upper_bound( const key_type& x )                                         
        {                                                                            
            return iterator( this->base().
                             upper_bound( const_cast<key_type*>(&x) ) );           
        }                                                                            
                                                                                     
        const_iterator upper_bound( const key_type& x ) const                             
        {                                                                            
            return const_iterator( this->base().
                                   upper_bound( const_cast<key_type*>(&x) ) );             
        }                                                                            
                                                                                     
        iterator_range<iterator> equal_range( const key_type& x )                    
        {                                                                            
            std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,
                      BOOST_DEDUCED_TYPENAME base_type::ptr_iterator> 
                p = this->base().
                equal_range( const_cast<key_type*>(&x) );   
            return make_iterator_range( iterator( p.first ), 
                                        iterator( p.second ) );      
        }                                                                            
                                                                                     
        iterator_range<const_iterator> equal_range( const key_type& x ) const  
        {                                                                            
            std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_const_iterator,
                      BOOST_DEDUCED_TYPENAME base_type::ptr_const_iterator> 
                p = this->base().
                equal_range( const_cast<key_type*>(&x) ); 
            return make_iterator_range( const_iterator( p.first ), 
                                        const_iterator( p.second ) );    
        }    

    protected:
        size_type bucket( const key_type& key ) const
        {
            return this->base().bucket( const_cast<key_type*>(&key) );
        }
    };

} // ptr_container_detail

    /////////////////////////////////////////////////////////////////////////
    // ptr_set_adapter
    /////////////////////////////////////////////////////////////////////////
  
    template
    <
        class Key,
        class VoidPtrSet, 
        class CloneAllocator = heap_clone_allocator,
        bool  Ordered        = true
    >
    class ptr_set_adapter : 
        public ptr_container_detail::ptr_set_adapter_base<Key,VoidPtrSet,CloneAllocator,Ordered>
    {
        typedef ptr_container_detail::ptr_set_adapter_base<Key,VoidPtrSet,CloneAllocator,Ordered> 
            base_type;
    
    public: // typedefs
       
        typedef BOOST_DEDUCED_TYPENAME base_type::iterator
                     iterator;                 
        typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator
                     const_iterator;                 
        typedef BOOST_DEDUCED_TYPENAME base_type::size_type
                     size_type;    
        typedef Key  key_type;
        typedef BOOST_DEDUCED_TYPENAME base_type::auto_type
                     auto_type;
        typedef BOOST_DEDUCED_TYPENAME VoidPtrSet::allocator_type
                     allocator_type;        
    private:
        
        template< typename II >                                               
        void set_basic_clone_and_insert( II first, II last ) // basic                 
        {                                                                     
            while( first != last )                                            
            {           
                if( this->find( *first ) == this->end() )
                    insert( CloneAllocator::allocate_clone( *first ) ); // strong, commit
                ++first;                                                      
            }                                                                 
        }                         

    public:
        ptr_set_adapter()
        { }

        template< class SizeType >
        ptr_set_adapter( SizeType n, 
                         ptr_container_detail::unordered_associative_container_tag tag )
          : base_type( n, tag )
        { }
        
        template< class Comp >
        explicit ptr_set_adapter( const Comp& comp,
                                  const allocator_type& a ) 
          : base_type( comp, a ) 
        {
            BOOST_ASSERT( this->empty() ); 
        }

        template< class Hash, class Pred, class Allocator >
        ptr_set_adapter( const Hash& hash,
                         const Pred& pred,
                         const Allocator& a )
         : base_type( hash, pred, a )
        { }

        template< class InputIterator >
        ptr_set_adapter( InputIterator first, InputIterator last )
         : base_type( first, last )
        { }

        template< class InputIterator, class Compare, class Allocator >
        ptr_set_adapter( InputIterator first, InputIterator last, 
                         const Compare& comp,
                         const Allocator a = Allocator() )
          : base_type( comp, a )
        {
            BOOST_ASSERT( this->empty() );
            set_basic_clone_and_insert( first, last );
        }

        template< class InputIterator, class Hash, class Pred, class Allocator >
        ptr_set_adapter( InputIterator first, InputIterator last,
                         const Hash& hash,
                         const Pred& pred,
                         const Allocator& a )
          : base_type( first, last, hash, pred, a )
        { }

        explicit ptr_set_adapter( const ptr_set_adapter& r )
          : base_type( r )
        { }

        template< class U, class Set, class CA, bool b >
        explicit ptr_set_adapter( const ptr_set_adapter<U,Set,CA,b>& r )
          : base_type( r )
        { }
        
        template< class PtrContainer >
        explicit ptr_set_adapter( std::auto_ptr<PtrContainer> clone )
         : base_type( clone )
        { }

        template< class U, class Set, class CA, bool b >
        ptr_set_adapter& operator=( const ptr_set_adapter<U,Set,CA,b>& r ) 
        {
            base_type::operator=( r );
            return *this;
        }

        template< class T >
        void operator=( std::auto_ptr<T> r ) 
        {
            base_type::operator=( r );
        }

        std::pair<iterator,bool> insert( key_type* x ) // strong                      
        {       
            this->enforce_null_policy( x, "Null pointer in 'ptr_set::insert()'" );
            
            auto_type ptr( x );                                
            std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,bool>
                 res = this->base().insert( x );       
            if( res.second )                                                 
                ptr.release();                                                  
            return std::make_pair( iterator( res.first ), res.second );     
        }

        template< class U >
        std::pair<iterator,bool> insert( std::auto_ptr<U> x )
        {
            return insert( x.release() );
        }

        
        iterator insert( iterator where, key_type* x ) // strong
        {
            this->enforce_null_policy( x, "Null pointer in 'ptr_set::insert()'" );

            auto_type ptr( x );                                
            BOOST_DEDUCED_TYPENAME base_type::ptr_iterator 
                res = this->base().insert( where.base(), x );
            if( *res == x )                                                 
                ptr.release();                                                  
            return iterator( res);
        }

        template< class U >
        iterator insert( iterator where, std::auto_ptr<U> x )
        {
            return insert( where, x.release() );
        }
        
        template< typename InputIterator >
        void insert( InputIterator first, InputIterator last ) // basic
        {
            set_basic_clone_and_insert( first, last );
        }

#if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
#else    
        
        template< class Range >
        BOOST_DEDUCED_TYPENAME
        boost::disable_if< ptr_container_detail::is_pointer_or_integral<Range> >::type
        insert( const Range& r )
        {
            insert( boost::begin(r), boost::end(r) );
        }

#endif        

        template< class PtrSetAdapter >
        bool transfer( BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator object, 
                       PtrSetAdapter& from ) // strong
        {
            return this->single_transfer( object, from );
        }

        template< class PtrSetAdapter >
        size_type 
        transfer( BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator first, 
                  BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator last, 
                  PtrSetAdapter& from ) // basic
        {
            return this->single_transfer( first, last, from );
        }

#if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
#else    

        template< class PtrSetAdapter, class Range >
        BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_same< Range,
                            BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator >,
                                                            size_type >::type
        transfer( const Range& r, PtrSetAdapter& from ) // basic
        {
            return transfer( boost::begin(r), boost::end(r), from );
        }

#endif

        template< class PtrSetAdapter >
        size_type transfer( PtrSetAdapter& from ) // basic
        {
            return transfer( from.begin(), from.end(), from );
        }

    };
    
    /////////////////////////////////////////////////////////////////////////
    // ptr_multiset_adapter
    /////////////////////////////////////////////////////////////////////////

    template
    < 
        class Key,
        class VoidPtrMultiSet, 
        class CloneAllocator = heap_clone_allocator,
        bool Ordered         = true 
    >
    class ptr_multiset_adapter : 
        public ptr_container_detail::ptr_set_adapter_base<Key,VoidPtrMultiSet,CloneAllocator,Ordered>
    {
         typedef ptr_container_detail::ptr_set_adapter_base<Key,VoidPtrMultiSet,CloneAllocator,Ordered> base_type;
    
    public: // typedefs
    
        typedef BOOST_DEDUCED_TYPENAME base_type::iterator   
                       iterator;          
        typedef BOOST_DEDUCED_TYPENAME base_type::size_type
                       size_type;
        typedef Key    key_type;
        typedef BOOST_DEDUCED_TYPENAME base_type::auto_type
                       auto_type;
        typedef BOOST_DEDUCED_TYPENAME VoidPtrMultiSet::allocator_type
                       allocator_type;        
    private:
        template< typename II >                                               
        void set_basic_clone_and_insert( II first, II last ) // basic                 
        {               
            while( first != last )                                            
            {           
                insert( CloneAllocator::allocate_clone( *first ) ); // strong, commit                              
                ++first;                                                     
            }                                                                 
        }                         
    
    public:
        ptr_multiset_adapter()
        { }

        template< class SizeType >
        ptr_multiset_adapter( SizeType n, 
                              ptr_container_detail::unordered_associative_container_tag tag )
          : base_type( n, tag )
        { }

        template< class Comp >
        explicit ptr_multiset_adapter( const Comp& comp,
                                       const allocator_type& a )
        : base_type( comp, a ) 
        { }

        template< class Hash, class Pred, class Allocator >
        ptr_multiset_adapter( const Hash& hash,
                              const Pred& pred,
                              const Allocator& a )
         : base_type( hash, pred, a )
        { }

        template< class InputIterator >
        ptr_multiset_adapter( InputIterator first, InputIterator last )
         : base_type( first, last )
        { }
        
        template< class InputIterator, class Comp >
        ptr_multiset_adapter( InputIterator first, InputIterator last,
                              const Comp& comp,
                              const allocator_type& a = allocator_type() )
        : base_type( comp, a ) 
        {
            set_basic_clone_and_insert( first, last );
        }

        template< class InputIterator, class Hash, class Pred, class Allocator >
        ptr_multiset_adapter( InputIterator first, InputIterator last,
                              const Hash& hash,
                              const Pred& pred,
                              const Allocator& a )
         : base_type( first, last, hash, pred, a )
        { }
                
        template< class U, class Set, class CA, bool b >
        explicit ptr_multiset_adapter( const ptr_multiset_adapter<U,Set,CA,b>& r )
          : base_type( r )
        { }
        
        template< class PtrContainer >
        explicit ptr_multiset_adapter( std::auto_ptr<PtrContainer> clone )
         : base_type( clone )
        { }

        template< class U, class Set, class CA, bool b >
        ptr_multiset_adapter& operator=( const ptr_multiset_adapter<U,Set,CA,b>& r ) 
        {
            base_type::operator=( r );
            return *this;
        }
        
        template< class T >
        void operator=( std::auto_ptr<T> r ) 
        {
            base_type::operator=( r ); 
        }

        iterator insert( iterator before, key_type* x ) // strong  
        {
            return base_type::insert( before, x ); 
        } 

        template< class U >
        iterator insert( iterator before, std::auto_ptr<U> x )
        {
            return insert( before, x.release() );
        }
    
        iterator insert( key_type* x ) // strong                                      
        {   
            this->enforce_null_policy( x, "Null pointer in 'ptr_multiset::insert()'" );
    
            auto_type ptr( x );                                
            BOOST_DEDUCED_TYPENAME base_type::ptr_iterator
                 res = this->base().insert( x );                         
            ptr.release();                                                      
            return iterator( res );                                             
        }

        template< class U >
        iterator insert( std::auto_ptr<U> x )
        {
            return insert( x.release() );
        }
    
        template< typename InputIterator >
        void insert( InputIterator first, InputIterator last ) // basic
        {
            set_basic_clone_and_insert( first, last );
        }

#if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
#else    
        
        template< class Range >
        BOOST_DEDUCED_TYPENAME
        boost::disable_if< ptr_container_detail::is_pointer_or_integral<Range> >::type
        insert( const Range& r )
        {
            insert( boost::begin(r), boost::end(r) );
        }

#endif

        template< class PtrSetAdapter >
        void transfer( BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator object, 
                       PtrSetAdapter& from ) // strong
        {
            this->multi_transfer( object, from );
        }

        template< class PtrSetAdapter >
        size_type transfer( BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator first, 
                            BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator last, 
                            PtrSetAdapter& from ) // basic
        {
            return this->multi_transfer( first, last, from );
        }

#if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
#else    
        
        template< class PtrSetAdapter, class Range >
        BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_same< Range,
                       BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator >, size_type >::type
        transfer(  const Range& r, PtrSetAdapter& from ) // basic
        {
            return transfer( boost::begin(r), boost::end(r), from );
        }

#endif        

        template< class PtrSetAdapter >
        void transfer( PtrSetAdapter& from ) // basic
        {
            transfer( from.begin(), from.end(), from );
            BOOST_ASSERT( from.empty() );
        }
        
    };

} // namespace 'boost'  

#endif
