|
||||
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
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |