/*=============================================================================
    Copyright (c) 2003 Giovanni Bajo
    Copyright (c) 2003 Thomas Witt
    Copyright (c) 2003 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)
=============================================================================*/

///////////////////////////////////////////////////////////////////////////////
//
//  File Iterator structure
//
//  The new structure is designed on layers. The top class (used by the user)
//  is file_iterator, which implements a full random access iterator through
//  the file, and some specific member functions (constructor that opens
//  the file, make_end() to generate the end iterator, operator bool to check
//  if the file was opened correctly).
//
//  file_iterator implements the random access iterator interface by the means
//  of boost::iterator_adaptor, that is inhering an object created with it.
//  iterator_adaptor gets a low-level file iterator implementation (with just
//  a few member functions) and a policy (that basically describes to it how
//  the low-level file iterator interface is). The advantage is that
//  with boost::iterator_adaptor only 5 functions are needed to implement
//  a fully conformant random access iterator, instead of dozens of functions
//  and operators.
//
//  There are two low-level file iterators implemented in this module. The
//  first (std_file_iterator) uses cstdio stream functions (fopen/fread), which
//  support full buffering, and is available everywhere (it's standard C++).
//  The second (mmap_file_iterator) is currently available only on Windows
//  platforms, and uses memory mapped files, which gives a decent speed boost.
//
///////////////////////////////////////////////////////////////////////////////
//
//  TODO LIST:
//
//  - In the Win32 mmap iterator, we could check if keeping a handle to the
//    opened file is really required. If it's not, we can just store the file
//    length (for make_end()) and save performance. Notice that this should be
//    tested under different Windows versions, the behaviour might change.
//  - Add some error support (by the means of some exceptions) in case of
//    low-level I/O failure.
//
///////////////////////////////////////////////////////////////////////////////

#ifndef BOOST_SPIRIT_FILE_ITERATOR_HPP
#define BOOST_SPIRIT_FILE_ITERATOR_HPP

#include <string>
#include <boost/config.hpp>
#include <boost/iterator_adaptors.hpp>
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/safe_bool.hpp>

#include <boost/spirit/home/classic/iterator/file_iterator_fwd.hpp>

#if !defined(BOOST_SPIRIT_FILEITERATOR_STD)
#  if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) \
      && !defined(BOOST_DISABLE_WIN32)
#    define BOOST_SPIRIT_FILEITERATOR_WINDOWS
#  elif defined(BOOST_HAS_UNISTD_H)
extern "C"
{
#    include <unistd.h>
}
#    ifdef _POSIX_MAPPED_FILES
#      define BOOST_SPIRIT_FILEITERATOR_POSIX
#    endif // _POSIX_MAPPED_FILES
#  endif // BOOST_HAS_UNISTD_H

#  if !defined(BOOST_SPIRIT_FILEITERATOR_WINDOWS) && \
      !defined(BOOST_SPIRIT_FILEITERATOR_POSIX)
#    define BOOST_SPIRIT_FILEITERATOR_STD
#  endif
#endif // BOOST_SPIRIT_FILEITERATOR_STD

///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {

BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN

template <
    typename CharT = char,
    typename BaseIterator =
#ifdef BOOST_SPIRIT_FILEITERATOR_STD
        fileiter_impl::std_file_iterator<CharT>
#else
        fileiter_impl::mmap_file_iterator<CharT>
#endif
> class file_iterator;

///////////////////////////////////////////////////////////////////////////////
namespace fileiter_impl {

    /////////////////////////////////////////////////////////////////////////
    //
    //  file_iter_generator
    //
    //  Template meta-function to invoke boost::iterator_adaptor
    //  NOTE: This cannot be moved into the implementation file because of
    //  a bug of MSVC 7.0 and previous versions (base classes types are
    //  looked up at compilation time, not instantion types, and
    //  file_iterator would break).
    //
    /////////////////////////////////////////////////////////////////////////

#if !defined(BOOST_ITERATOR_ADAPTORS_VERSION) || \
     BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
#error "Please use at least Boost V1.31.0 while compiling the file_iterator class!"
#else // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200

    template <typename CharT, typename BaseIteratorT>
    struct file_iter_generator
    {
    public:
        typedef BaseIteratorT adapted_t;
        typedef typename adapted_t::value_type value_type;

        typedef boost::iterator_adaptor <
            file_iterator<CharT, BaseIteratorT>,
            adapted_t,
            value_type const,
            std::random_access_iterator_tag,
            boost::use_default,
            std::ptrdiff_t
        > type;
    };

#endif // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200

///////////////////////////////////////////////////////////////////////////////
} /* namespace impl */


///////////////////////////////////////////////////////////////////////////////
//
//  file_iterator
//
//  Iterates through an opened file.
//
//  The main iterator interface is implemented by the iterator_adaptors
//  library, which wraps a conforming iterator interface around the
//  impl::BaseIterator class. This class merely derives the iterator_adaptors
//  generated class to implement the custom constructors and make_end()
//  member function.
//
///////////////////////////////////////////////////////////////////////////////

template<typename CharT, typename BaseIteratorT>
class file_iterator
    : public fileiter_impl::file_iter_generator<CharT, BaseIteratorT>::type,
      public safe_bool<file_iterator<CharT, BaseIteratorT> >
{
private:
    typedef typename
        fileiter_impl::file_iter_generator<CharT, BaseIteratorT>::type
        base_t;
    typedef typename
        fileiter_impl::file_iter_generator<CharT, BaseIteratorT>::adapted_t
        adapted_t;

public:
    file_iterator()
    {}

    file_iterator(std::string fileName)
    :   base_t(adapted_t(fileName))
    {}

    file_iterator(const base_t& iter)
    :   base_t(iter)
    {}

    inline file_iterator& operator=(const base_t& iter);
    file_iterator make_end(void);

    // operator bool. This borrows a trick from boost::shared_ptr to avoid
    //   to interfere with arithmetic operations.
    bool operator_bool(void) const
    { return this->base(); }

private:
    friend class ::boost::iterator_core_access;

    typename base_t::reference dereference() const
    {
        return this->base_reference().get_cur_char();
    }

    void increment()
    {
        this->base_reference().next_char();
    }

    void decrement()
    {
        this->base_reference().prev_char();
    }

    void advance(typename base_t::difference_type n)
    {
        this->base_reference().advance(n);
    }

    template <
        typename OtherDerivedT, typename OtherIteratorT,
        typename V, typename C, typename R, typename D
    >
    typename base_t::difference_type distance_to(
        iterator_adaptor<OtherDerivedT, OtherIteratorT, V, C, R, D>
        const &x) const
    {
        return x.base().distance(this->base_reference());
    }
};

///////////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_CLASSIC_NAMESPACE_END

}} /* namespace BOOST_SPIRIT_CLASSIC_NS */

///////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/home/classic/iterator/impl/file_iterator.ipp> /* implementation */

#endif /* BOOST_SPIRIT_FILE_ITERATOR_HPP */

