//  Copyright (c) 2001 Daniel C. Nuffer
//  Copyright (c) 2001-2010 Hartmut Kaiser
// 
//  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)

#if !defined(BOOST_SPIRIT_ITERATOR_SPLIT_DEQUE_POLICY_APR_06_2008_0138PM)
#define BOOST_SPIRIT_ITERATOR_SPLIT_DEQUE_POLICY_APR_06_2008_0138PM

#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
#include <boost/assert.hpp>
#include <vector>

namespace boost { namespace spirit { namespace iterator_policies
{
    ///////////////////////////////////////////////////////////////////////////
    //  class split_std_deque
    //
    //  Implementation of the StoragePolicy used by multi_pass
    //  This stores all data in a std::vector (despite its name), and keeps an 
    //  offset to the current position. It stores all the data unless there is 
    //  only one iterator using the queue.
    // 
    ///////////////////////////////////////////////////////////////////////////
    struct split_std_deque
    {
        enum { threshold = 16 };

        ///////////////////////////////////////////////////////////////////////
        template <typename Value>
        class unique //: public detail::default_storage_policy
        {
        private:
            typedef std::vector<Value> queue_type;

        protected:
            unique() : queued_position(0) {}

            unique(unique const& x)
              : queued_position(x.queued_position) {}

            void swap(unique& x)
            {
                boost::swap(queued_position, x.queued_position);
            }

            // This is called when the iterator is dereferenced.  It's a 
            // template method so we can recover the type of the multi_pass 
            // iterator and call advance_input and input_is_valid.
            template <typename MultiPass>
            static typename MultiPass::reference 
            dereference(MultiPass const& mp)
            {
                queue_type& queue = mp.shared()->queued_elements;
                typename queue_type::size_type size = queue.size();

                BOOST_ASSERT(mp.queued_position <= size);

                if (mp.queued_position == size)
                {
                    // check if this is the only iterator
                    if (size >= threshold && MultiPass::is_unique(mp))
                    {
                        // free up the memory used by the queue.
                        queue.clear();
                        mp.queued_position = 0;
                    }
                    return MultiPass::get_input(mp);
                }

                return queue[mp.queued_position];
            }

            // This is called when the iterator is incremented. It's a template
            // method so we can recover the type of the multi_pass iterator
            // and call is_unique and advance_input.
            template <typename MultiPass>
            static void increment(MultiPass& mp)
            {
                queue_type& queue = mp.shared()->queued_elements;
                typename queue_type::size_type size = queue.size();

                BOOST_ASSERT(mp.queued_position <= size);

//                 // do not increment iterator as long as the current token is
//                 // invalid
//                 if (size > 0 && !MultiPass::input_is_valid(mp, queue[mp.queued_position-1]))
//                     return;

                if (mp.queued_position == size)
                {
                    // check if this is the only iterator
                    if (size >= threshold && MultiPass::is_unique(mp))
                    {
                        // free up the memory used by the queue. we avoid 
                        // clearing the queue on every increment, though, 
                        // because this would be too time consuming
                        queue.clear();
                        mp.queued_position = 0;
                    }
                    else
                    {
                        queue.push_back(MultiPass::get_input(mp));
                        ++mp.queued_position;
                    }
                    MultiPass::advance_input(mp);
                }
                else
                {
                    ++mp.queued_position;
                }
            }

            // called to forcibly clear the queue
            template <typename MultiPass>
            static void clear_queue(MultiPass& mp)
            {
                mp.shared()->queued_elements.clear();
                mp.queued_position = 0;
            }

            // called to determine whether the iterator is an eof iterator
            template <typename MultiPass>
            static bool is_eof(MultiPass const& mp)
            {
                return mp.queued_position == mp.shared()->queued_elements.size() 
                    && MultiPass::input_at_eof(mp);
            }

            // called by operator==
            template <typename MultiPass>
            static bool equal_to(MultiPass const& mp, MultiPass const& x) 
            {
                return mp.queued_position == x.queued_position;
            }

            // called by operator<
            template <typename MultiPass>
            static bool less_than(MultiPass const& mp, MultiPass const& x)
            {
                return mp.queued_position < x.queued_position;
            }

            template <typename MultiPass>
            static void destroy(MultiPass&) {}

        protected:
            mutable typename queue_type::size_type queued_position;
        }; 

        ///////////////////////////////////////////////////////////////////////
        template <typename Value>
        struct shared
        {
            shared() 
            {
                queued_elements.reserve(threshold); 
            }

            typedef std::vector<Value> queue_type;
            queue_type queued_elements;
        }; 

    }; // split_std_deque

}}}

#endif

