Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-16 09:33:22

0001 /*=============================================================================
0002     Copyright (c) 2003 Giovanni Bajo
0003     Copyright (c) 2003 Thomas Witt
0004     Copyright (c) 2003 Hartmut Kaiser
0005     http://spirit.sourceforge.net/
0006 
0007   Distributed under the Boost Software License, Version 1.0. (See accompanying
0008   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 =============================================================================*/
0010 
0011 ///////////////////////////////////////////////////////////////////////////////
0012 //
0013 //  File Iterator structure
0014 //
0015 //  The new structure is designed on layers. The top class (used by the user)
0016 //  is file_iterator, which implements a full random access iterator through
0017 //  the file, and some specific member functions (constructor that opens
0018 //  the file, make_end() to generate the end iterator, operator bool to check
0019 //  if the file was opened correctly).
0020 //
0021 //  file_iterator implements the random access iterator interface by the means
0022 //  of boost::iterator_adaptor, that is inhering an object created with it.
0023 //  iterator_adaptor gets a low-level file iterator implementation (with just
0024 //  a few member functions) and a policy (that basically describes to it how
0025 //  the low-level file iterator interface is). The advantage is that
0026 //  with boost::iterator_adaptor only 5 functions are needed to implement
0027 //  a fully conformant random access iterator, instead of dozens of functions
0028 //  and operators.
0029 //
0030 //  There are two low-level file iterators implemented in this module. The
0031 //  first (std_file_iterator) uses cstdio stream functions (fopen/fread), which
0032 //  support full buffering, and is available everywhere (it's standard C++).
0033 //  The second (mmap_file_iterator) is currently available only on Windows
0034 //  platforms, and uses memory mapped files, which gives a decent speed boost.
0035 //
0036 ///////////////////////////////////////////////////////////////////////////////
0037 //
0038 //  TODO LIST:
0039 //
0040 //  - In the Win32 mmap iterator, we could check if keeping a handle to the
0041 //    opened file is really required. If it's not, we can just store the file
0042 //    length (for make_end()) and save performance. Notice that this should be
0043 //    tested under different Windows versions, the behaviour might change.
0044 //  - Add some error support (by the means of some exceptions) in case of
0045 //    low-level I/O failure.
0046 //
0047 ///////////////////////////////////////////////////////////////////////////////
0048 
0049 #ifndef BOOST_SPIRIT_FILE_ITERATOR_HPP
0050 #define BOOST_SPIRIT_FILE_ITERATOR_HPP
0051 
0052 #include <string>
0053 #include <boost/config.hpp>
0054 #include <boost/iterator_adaptors.hpp>
0055 #include <boost/spirit/home/classic/namespace.hpp>
0056 #include <boost/spirit/home/classic/core/safe_bool.hpp>
0057 
0058 #include <boost/spirit/home/classic/iterator/file_iterator_fwd.hpp>
0059 
0060 #if !defined(BOOST_SPIRIT_FILEITERATOR_STD)
0061 #  if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) \
0062       && !defined(BOOST_DISABLE_WIN32)
0063 #    define BOOST_SPIRIT_FILEITERATOR_WINDOWS
0064 #  elif defined(BOOST_HAS_UNISTD_H)
0065 extern "C"
0066 {
0067 #    include <unistd.h>
0068 }
0069 #    ifdef _POSIX_MAPPED_FILES
0070 #      define BOOST_SPIRIT_FILEITERATOR_POSIX
0071 #    endif // _POSIX_MAPPED_FILES
0072 #  endif // BOOST_HAS_UNISTD_H
0073 
0074 #  if !defined(BOOST_SPIRIT_FILEITERATOR_WINDOWS) && \
0075       !defined(BOOST_SPIRIT_FILEITERATOR_POSIX)
0076 #    define BOOST_SPIRIT_FILEITERATOR_STD
0077 #  endif
0078 #endif // BOOST_SPIRIT_FILEITERATOR_STD
0079 
0080 ///////////////////////////////////////////////////////////////////////////////
0081 namespace boost { namespace spirit {
0082 
0083 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
0084 
0085 template <
0086     typename CharT = char,
0087     typename BaseIterator =
0088 #ifdef BOOST_SPIRIT_FILEITERATOR_STD
0089         fileiter_impl::std_file_iterator<CharT>
0090 #else
0091         fileiter_impl::mmap_file_iterator<CharT>
0092 #endif
0093 > class file_iterator;
0094 
0095 ///////////////////////////////////////////////////////////////////////////////
0096 namespace fileiter_impl {
0097 
0098     /////////////////////////////////////////////////////////////////////////
0099     //
0100     //  file_iter_generator
0101     //
0102     //  Template meta-function to invoke boost::iterator_adaptor
0103     //  NOTE: This cannot be moved into the implementation file because of
0104     //  a bug of MSVC 7.0 and previous versions (base classes types are
0105     //  looked up at compilation time, not instantion types, and
0106     //  file_iterator would break).
0107     //
0108     /////////////////////////////////////////////////////////////////////////
0109 
0110 #if !defined(BOOST_ITERATOR_ADAPTORS_VERSION) || \
0111      BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
0112 #error "Please use at least Boost V1.31.0 while compiling the file_iterator class!"
0113 #else // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
0114 
0115     template <typename CharT, typename BaseIteratorT>
0116     struct file_iter_generator
0117     {
0118     public:
0119         typedef BaseIteratorT adapted_t;
0120         typedef typename adapted_t::value_type value_type;
0121 
0122         typedef boost::iterator_adaptor <
0123             file_iterator<CharT, BaseIteratorT>,
0124             adapted_t,
0125             value_type const,
0126             std::random_access_iterator_tag,
0127             boost::use_default,
0128             std::ptrdiff_t
0129         > type;
0130     };
0131 
0132 #endif // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
0133 
0134 ///////////////////////////////////////////////////////////////////////////////
0135 } /* namespace impl */
0136 
0137 
0138 ///////////////////////////////////////////////////////////////////////////////
0139 //
0140 //  file_iterator
0141 //
0142 //  Iterates through an opened file.
0143 //
0144 //  The main iterator interface is implemented by the iterator_adaptors
0145 //  library, which wraps a conforming iterator interface around the
0146 //  impl::BaseIterator class. This class merely derives the iterator_adaptors
0147 //  generated class to implement the custom constructors and make_end()
0148 //  member function.
0149 //
0150 ///////////////////////////////////////////////////////////////////////////////
0151 
0152 template<typename CharT, typename BaseIteratorT>
0153 class file_iterator
0154     : public fileiter_impl::file_iter_generator<CharT, BaseIteratorT>::type,
0155       public safe_bool<file_iterator<CharT, BaseIteratorT> >
0156 {
0157 private:
0158     typedef typename
0159         fileiter_impl::file_iter_generator<CharT, BaseIteratorT>::type
0160         base_t;
0161     typedef typename
0162         fileiter_impl::file_iter_generator<CharT, BaseIteratorT>::adapted_t
0163         adapted_t;
0164 
0165 public:
0166     file_iterator()
0167     {}
0168 
0169     file_iterator(std::string const& fileName)
0170     :   base_t(adapted_t(fileName))
0171     {}
0172 
0173     file_iterator(const base_t& iter)
0174     :   base_t(iter)
0175     {}
0176 
0177     inline file_iterator& operator=(const base_t& iter);
0178     file_iterator make_end(void);
0179 
0180     // operator bool. This borrows a trick from boost::shared_ptr to avoid
0181     //   to interfere with arithmetic operations.
0182     bool operator_bool(void) const
0183     { return this->base(); }
0184 
0185 private:
0186     friend class ::boost::iterator_core_access;
0187 
0188     typename base_t::reference dereference() const
0189     {
0190         return this->base_reference().get_cur_char();
0191     }
0192 
0193     void increment()
0194     {
0195         this->base_reference().next_char();
0196     }
0197 
0198     void decrement()
0199     {
0200         this->base_reference().prev_char();
0201     }
0202 
0203     void advance(typename base_t::difference_type n)
0204     {
0205         this->base_reference().advance(n);
0206     }
0207 
0208     template <
0209         typename OtherDerivedT, typename OtherIteratorT,
0210         typename V, typename C, typename R, typename D
0211     >
0212     typename base_t::difference_type distance_to(
0213         iterator_adaptor<OtherDerivedT, OtherIteratorT, V, C, R, D>
0214         const &x) const
0215     {
0216         return x.base().distance(this->base_reference());
0217     }
0218 };
0219 
0220 ///////////////////////////////////////////////////////////////////////////////
0221 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
0222 
0223 }} /* namespace BOOST_SPIRIT_CLASSIC_NS */
0224 
0225 ///////////////////////////////////////////////////////////////////////////////
0226 #include <boost/spirit/home/classic/iterator/impl/file_iterator.ipp> /* implementation */
0227 
0228 #endif /* BOOST_SPIRIT_FILE_ITERATOR_HPP */
0229