//  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_BUFFERING_ITERATOR_INPUT_ITERATOR_POLICY_MAR_04_2010_1224AM)
#define BOOST_SPIRIT_BUFFERING_ITERATOR_INPUT_ITERATOR_POLICY_MAR_04_2010_1224AM

#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
#include <boost/spirit/home/support/iterators/detail/input_iterator_policy.hpp>
#include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits
#include <boost/assert.hpp>

namespace boost { namespace spirit { namespace iterator_policies
{
    ///////////////////////////////////////////////////////////////////////////
    //  class input_iterator
    //
    //  Implementation of the InputPolicy used by multi_pass, this is different 
    //  from the input_iterator policy only as it is buffering the last input
    //  character to allow returning it by reference. This is needed for
    //  wrapping iterators not buffering the last item (such as the 
    //  std::istreambuf_iterator). Unfortunately there is no way to 
    //  automatically figure this out at compile time.
    // 
    //  The buffering_input_iterator encapsulates an input iterator of type T
    ///////////////////////////////////////////////////////////////////////////
    struct buffering_input_iterator
    {
        ///////////////////////////////////////////////////////////////////////
        template <typename T>
        class unique // : public detail::default_input_policy
        {
        private:
            typedef
                typename boost::detail::iterator_traits<T>::value_type
            result_type;

        public:
            typedef
                typename boost::detail::iterator_traits<T>::difference_type
            difference_type;
            typedef
                typename boost::detail::iterator_traits<T>::difference_type
            distance_type;
            typedef
                typename boost::detail::iterator_traits<T>::pointer
            pointer;
            typedef
                typename boost::detail::iterator_traits<T>::reference
            reference;
            typedef result_type value_type;

        protected:
            unique() {}
            explicit unique(T x) {}

            void swap(unique&) {}

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

            template <typename MultiPass>
            static typename MultiPass::reference get_input(MultiPass& mp)
            {
                return mp.shared()->get_input();
            }

            template <typename MultiPass>
            static void advance_input(MultiPass& mp)
            {
                BOOST_ASSERT(0 != mp.shared());
                mp.shared()->advance_input();
            }

            // test, whether we reached the end of the underlying stream
            template <typename MultiPass>
            static bool input_at_eof(MultiPass const& mp) 
            {
                static T const end_iter;
                return mp.shared()->input_ == end_iter;
            }

            template <typename MultiPass>
            static bool input_is_valid(MultiPass const& mp, value_type const& t) 
            {
                return mp.shared()->input_is_valid_;
            }

            // no unique data elements
        };

        ///////////////////////////////////////////////////////////////////////
        template <typename T>
        struct shared
        {
            typedef
                typename boost::detail::iterator_traits<T>::value_type
            result_type;

            explicit shared(T const& input) 
              : input_(input), curtok_(0), input_is_valid_(false) {}

            void advance_input()
            {
                ++input_;
                input_is_valid_ = false;
            }

            result_type& get_input()
            {
                if (!input_is_valid_) {
                    curtok_ = *input_;
                    input_is_valid_ = true;
                }
                return curtok_;
            }

            T input_;
            result_type curtok_;
            bool input_is_valid_;
        };
    };

}}}

#endif
