]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/spirit/home/qi/stream/detail/iterator_source.hpp
buildsys: switch source download to quincy
[ceph.git] / ceph / src / boost / boost / spirit / home / qi / stream / detail / iterator_source.hpp
CommitLineData
7c673cae
FG
1/*=============================================================================
2 Copyright (c) 2001-2011 Hartmut Kaiser
3
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6==============================================================================*/
7#if !defined(BOOST_SPIRIT_ITERATOR_ISTREAM_MAY_05_2007_0110PM)
8#define BOOST_SPIRIT_ITERATOR_ISTREAM_MAY_05_2007_0110PM
9
10#if defined(_MSC_VER)
11#pragma once
12#endif
13
14#include <boost/iostreams/stream.hpp>
92f5a8d4 15#include <iterator> // for std::iterator_traits, std::distance
7c673cae
FG
16
17///////////////////////////////////////////////////////////////////////////////
18namespace boost { namespace spirit { namespace qi { namespace detail
19{
20 ///////////////////////////////////////////////////////////////////////////
21 template <typename Iterator>
92f5a8d4 22 struct base_iterator_source
7c673cae 23 {
92f5a8d4 24 typedef typename std::iterator_traits<Iterator>::value_type char_type;
7c673cae
FG
25 typedef boost::iostreams::seekable_device_tag category;
26
92f5a8d4 27 base_iterator_source (Iterator const& first_, Iterator const& last_)
7c673cae
FG
28 : first(first_), last(last_), pos(0)
29 {}
30
31 // Read up to n characters from the input sequence into the buffer s,
32 // returning the number of characters read, or -1 to indicate
33 // end-of-sequence.
34 std::streamsize read (char_type* s, std::streamsize n)
35 {
36 if (first == last)
37 return -1;
38
39 std::streamsize bytes_read = 0;
40 while (n--) {
41 *s = *first;
42 ++s; ++bytes_read;
43 if (++first == last)
44 break;
45 }
46
47 pos += bytes_read;
48 return bytes_read;
49 }
50
51 // Write is implemented only to satisfy the requirements of a
52 // boost::iostreams::seekable_device. We need to have see support to
53 // be able to figure out how many characters have been actually
54 // consumed by the stream.
55 std::streamsize write(const char_type*, std::streamsize)
56 {
57 BOOST_ASSERT(false); // not supported
58 return -1;
59 }
60
61 std::streampos seek(boost::iostreams::stream_offset, std::ios_base::seekdir way)
62 {
92f5a8d4 63 (void)way;
7c673cae
FG
64 BOOST_ASSERT(way == std::ios_base::cur); // only support queries
65 return pos; // return current position
66 }
67
68 Iterator first;
69 Iterator const& last;
70 std::streamsize pos;
71
7c673cae 72 // silence MSVC warning C4512: assignment operator could not be generated
92f5a8d4
TL
73 BOOST_DELETED_FUNCTION(base_iterator_source& operator= (base_iterator_source const&))
74 };
75
76 template <typename Iterator, typename Enable = void>
77 struct iterator_source : base_iterator_source<Iterator>
78 {
79 typedef base_iterator_source<Iterator> base_type;
80
81 iterator_source (Iterator const& first_, Iterator const& last_)
82 : base_type(first_, last_) {}
83 };
84
85 // Specialization for random-access iterators. This also allows compilers
86 // to fully optimize the case when the source range is contiguous
87 template <typename Iterator>
88 struct iterator_source<
89 Iterator,
90 typename boost::enable_if_c<boost::is_convertible<
91 typename std::iterator_traits<Iterator>::iterator_category, std::random_access_iterator_tag>::value>::type
92 > : base_iterator_source<Iterator>
93 {
94 typedef base_iterator_source<Iterator> base_type;
95
96 iterator_source (Iterator const& first_, Iterator const& last_)
97 : base_type(first_, last_) {}
98
99 typedef typename base_type::char_type char_type;
100 using base_type::first;
101 using base_type::last;
102 using base_type::pos;
103
104 // Read up to n characters from the input sequence into the buffer s,
105 // returning the number of characters read, or -1 to indicate
106 // end-of-sequence.
107 std::streamsize read (char_type* s, std::streamsize n)
108 {
109 if (first == last)
110 return -1;
111
112 n = (std::min)(static_cast<std::streamsize>(last - first), n);
113
114 typedef typename std::iterator_traits<Iterator>::difference_type diff_type;
115
116 // copy_n is only part of c++11, so emulate it
117 std::copy(first, first + static_cast<diff_type>(n), s);
118 first += static_cast<diff_type>(n);
119 pos += n;
120
121 return n;
122 }
7c673cae
FG
123 };
124
125}}}}
126
127#endif