//  Copyright (c) 2001, Daniel C. Nuffer
//  Copyright (c) 2001-2010 Hartmut Kaiser
//  http://spirit.sourceforge.net/
// 
//  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_MULTI_PASS_MAR_16_2007_1124AM)
#define BOOST_SPIRIT_ITERATOR_MULTI_PASS_MAR_16_2007_1124AM

#include <boost/config.hpp>
#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/combine_policies.hpp>
#include <boost/limits.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/utility/base_from_member.hpp>

namespace boost { namespace spirit 
{
    ///////////////////////////////////////////////////////////////////////////
    // The default multi_pass instantiation uses a ref-counted std_deque scheme.
    ///////////////////////////////////////////////////////////////////////////
    template<typename T, typename Policies>
    class multi_pass 
      : private boost::base_from_member<
            typename Policies::BOOST_NESTED_TEMPLATE shared<T>*>
      , public Policies::BOOST_NESTED_TEMPLATE unique<T>
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
      , typename iterator_base_creator<T, typename Policies::input_policy>::type
#endif
    {
    private:
        // unique and shared data types
        typedef typename Policies::BOOST_NESTED_TEMPLATE unique<T> 
            policies_base_type;
        typedef typename Policies::BOOST_NESTED_TEMPLATE shared<T> 
            shared_data_type;

        typedef boost::base_from_member<shared_data_type*> member_base;

        // define the types the standard embedded iterator typedefs are taken 
        // from
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
        typedef typename iterator_base_creator<Input, T>::type iterator_type;
#else
        typedef typename policies_base_type::input_policy iterator_type;
#endif

    public:
        // standard iterator typedefs
        typedef std::forward_iterator_tag iterator_category;
        typedef typename iterator_type::value_type value_type;
        typedef typename iterator_type::difference_type difference_type;
        typedef typename iterator_type::distance_type distance_type;
        typedef typename iterator_type::reference reference;
        typedef typename iterator_type::pointer pointer;

        multi_pass() : member_base((shared_data_type*)0) {}

        explicit multi_pass(T& input)
          : member_base(new shared_data_type(input)), policies_base_type(input) {}

        explicit multi_pass(T const& input)
          : member_base(new shared_data_type(input)), policies_base_type(input) {}

        multi_pass(multi_pass const& x)
          : member_base(x.member), policies_base_type(x)
        {
            policies_base_type::clone(*this);
        }

#if BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
        // The standard library shipped with gcc-3.1 has a bug in
        // bits/basic_string.tcc. It tries to use iter::iter(0) to
        // construct an iterator. Ironically, this  happens in sanity
        // checking code that isn't required by the standard.
        // The workaround is to provide an additional constructor that
        // ignores its int argument and behaves like the default constructor.
        multi_pass(int) : member_base((shared_data_type*)0) {}
#endif // BOOST_WORKAROUND(__GLIBCPP__, == 20020514)

        ~multi_pass()
        {
            if (policies_base_type::release(*this)) {
                policies_base_type::destroy(*this);
                delete this->member;
            }
        }

        multi_pass& operator=(multi_pass const& x)
        {
            if (this != &x) {
                multi_pass temp(x);
                temp.swap(*this);
            }
            return *this;
        }

        void swap(multi_pass& x)
        {
            boost::swap(this->member, x.member);
            this->policies_base_type::swap(x);
        }

        reference operator*() const
        {
            policies_base_type::docheck(*this);
            return policies_base_type::dereference(*this);
        }
        pointer operator->() const
        {
            return &(operator*());
        }

        multi_pass& operator++()
        {
            policies_base_type::docheck(*this);
            policies_base_type::increment(*this);
            return *this;
        }
        multi_pass operator++(int)
        {
            multi_pass tmp(*this);
            ++*this;
            return tmp;
        }

        void clear_queue(BOOST_SCOPED_ENUM(traits::clear_mode) mode = 
            traits::clear_mode::clear_if_enabled)
        {
            if (mode == traits::clear_mode::clear_always || !inhibit_clear_queue())
                policies_base_type::clear_queue(*this);
        }
        bool inhibit_clear_queue() const
        {
            return this->member->inhibit_clear_queue_;
        }
        void inhibit_clear_queue(bool flag)
        {
            this->member->inhibit_clear_queue_ = flag;
        }

        bool operator==(multi_pass const& y) const
        {
            if (is_eof())
                return y.is_eof();
            if (y.is_eof())
                return false;

            return policies_base_type::equal_to(*this, y);
        }
        bool operator<(multi_pass const& y) const
        {
            return policies_base_type::less_than(*this, y);
        }

        bool operator!=(multi_pass const& y)
        {
            return !(*this == y);
        }
        bool operator>(multi_pass const& y)
        {
            return y < *this;
        }
        bool operator>=(multi_pass const& y)
        {
            return !(*this < y);
        }
        bool operator<=(multi_pass const& y)
        {
            return !(y < *this);
        }

        // allow access to base member
        shared_data_type* shared() const { return this->member; }

    private: // helper functions
        bool is_eof() const
        {
            return (0 == this->member) || policies_base_type::is_eof(*this);
        }
    };

    ///////////////////////////////////////////////////////////////////////////
    //  Generator function
    ///////////////////////////////////////////////////////////////////////////
    template <typename Policies, typename T>
    inline multi_pass<T, Policies>
    make_multi_pass(T& i)
    {
        return multi_pass<T, Policies>(i);
    }
    template <typename Policies, typename T>
    inline multi_pass<T, Policies>
    make_multi_pass(T const& i)
    {
        return multi_pass<T, Policies>(i);
    }

    ///////////////////////////////////////////////////////////////////////////
    template <typename T>
    inline multi_pass<T>
    make_default_multi_pass(T& i)
    {
        return multi_pass<T>(i);
    }
    template <typename T>
    inline multi_pass<T>
    make_default_multi_pass(T const& i)
    {
        return multi_pass<T>(i);
    }

    ///////////////////////////////////////////////////////////////////////////
    template <typename T, typename Policies>
    inline void 
    swap(multi_pass<T, Policies> &x, multi_pass<T, Policies> &y)
    {
        x.swap(y);
    }

    ///////////////////////////////////////////////////////////////////////////
    // define special functions allowing to integrate any multi_pass iterator
    // with expectation points
    namespace traits
    {
        template <typename T, typename Policies>
        void clear_queue(multi_pass<T, Policies>& mp
          , BOOST_SCOPED_ENUM(traits::clear_mode) mode)
        {
            mp.clear_queue(mode);
        }

        template <typename T, typename Policies>
        void inhibit_clear_queue(multi_pass<T, Policies>& mp, bool flag)
        {
            mp.inhibit_clear_queue(flag);
        }

        template <typename T, typename Policies>
        bool inhibit_clear_queue(multi_pass<T, Policies>& mp)
        {
            return mp.inhibit_clear_queue();
        }
    }

}} // namespace boost::spirit

#endif 


