123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- /*=============================================================================
- Copyright (c) 2001-2011 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_ITERATOR_ISTREAM_MAY_05_2007_0110PM)
- #define BOOST_SPIRIT_ITERATOR_ISTREAM_MAY_05_2007_0110PM
- #if defined(_MSC_VER)
- #pragma once
- #endif
- #include <boost/iostreams/stream.hpp>
- #include <iterator> // for std::iterator_traits, std::distance
- ///////////////////////////////////////////////////////////////////////////////
- namespace boost { namespace spirit { namespace qi { namespace detail
- {
- ///////////////////////////////////////////////////////////////////////////
- template <typename Iterator>
- struct base_iterator_source
- {
- typedef typename std::iterator_traits<Iterator>::value_type char_type;
- typedef boost::iostreams::seekable_device_tag category;
- base_iterator_source (Iterator const& first_, Iterator const& last_)
- : first(first_), last(last_), pos(0)
- {}
- // Read up to n characters from the input sequence into the buffer s,
- // returning the number of characters read, or -1 to indicate
- // end-of-sequence.
- std::streamsize read (char_type* s, std::streamsize n)
- {
- if (first == last)
- return -1;
- std::streamsize bytes_read = 0;
- while (n--) {
- *s = *first;
- ++s; ++bytes_read;
- if (++first == last)
- break;
- }
- pos += bytes_read;
- return bytes_read;
- }
- // Write is implemented only to satisfy the requirements of a
- // boost::iostreams::seekable_device. We need to have see support to
- // be able to figure out how many characters have been actually
- // consumed by the stream.
- std::streamsize write(const char_type*, std::streamsize)
- {
- BOOST_ASSERT(false); // not supported
- return -1;
- }
- std::streampos seek(boost::iostreams::stream_offset, std::ios_base::seekdir way)
- {
- (void)way;
- BOOST_ASSERT(way == std::ios_base::cur); // only support queries
- return pos; // return current position
- }
- Iterator first;
- Iterator const& last;
- std::streamsize pos;
- // silence MSVC warning C4512: assignment operator could not be generated
- BOOST_DELETED_FUNCTION(base_iterator_source& operator= (base_iterator_source const&))
- };
- template <typename Iterator, typename Enable = void>
- struct iterator_source : base_iterator_source<Iterator>
- {
- typedef base_iterator_source<Iterator> base_type;
- iterator_source (Iterator const& first_, Iterator const& last_)
- : base_type(first_, last_) {}
- };
- // Specialization for random-access iterators. This also allows compilers
- // to fully optimize the case when the source range is contiguous
- template <typename Iterator>
- struct iterator_source<
- Iterator,
- typename boost::enable_if_c<boost::is_convertible<
- typename std::iterator_traits<Iterator>::iterator_category, std::random_access_iterator_tag>::value>::type
- > : base_iterator_source<Iterator>
- {
- typedef base_iterator_source<Iterator> base_type;
- iterator_source (Iterator const& first_, Iterator const& last_)
- : base_type(first_, last_) {}
- typedef typename base_type::char_type char_type;
- using base_type::first;
- using base_type::last;
- using base_type::pos;
- // Read up to n characters from the input sequence into the buffer s,
- // returning the number of characters read, or -1 to indicate
- // end-of-sequence.
- std::streamsize read (char_type* s, std::streamsize n)
- {
- if (first == last)
- return -1;
- n = (std::min)(static_cast<std::streamsize>(last - first), n);
- typedef typename std::iterator_traits<Iterator>::difference_type diff_type;
- // copy_n is only part of c++11, so emulate it
- std::copy(first, first + static_cast<diff_type>(n), s);
- first += static_cast<diff_type>(n);
- pos += n;
- return n;
- }
- };
- }}}}
- #endif
|