annotate DEPENDENCIES/generic/include/boost/iostreams/detail/adapter/range_adapter.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
Chris@16 2 // (C) Copyright 2003-2007 Jonathan Turkanis
Chris@16 3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
Chris@16 4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
Chris@16 5
Chris@16 6 // See http://www.boost.org/libs/iostreams for documentation.
Chris@16 7
Chris@16 8 #ifndef BOOST_IOSTREAMS_DETAIL_RANGE_ADAPTER_HPP_INCLUDED
Chris@16 9 #define BOOST_IOSTREAMS_DETAIL_RANGE_ADAPTER_HPP_INCLUDED
Chris@16 10
Chris@16 11 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
Chris@16 12 # pragma once
Chris@16 13 #endif
Chris@16 14
Chris@16 15 #include <algorithm> // min.
Chris@16 16 #include <boost/assert.hpp>
Chris@16 17 #include <cstddef> // ptrdiff_t.
Chris@16 18 #include <iosfwd> // streamsize, streamoff.
Chris@16 19 #include <boost/detail/iterator.hpp> // boost::iterator_traits.
Chris@16 20 #include <boost/iostreams/categories.hpp>
Chris@16 21 #include <boost/iostreams/detail/error.hpp>
Chris@16 22 #include <boost/iostreams/positioning.hpp>
Chris@16 23 #include <boost/mpl/if.hpp>
Chris@16 24 #include <boost/throw_exception.hpp>
Chris@16 25 #include <boost/type_traits/is_convertible.hpp>
Chris@16 26 #include <boost/utility/enable_if.hpp>
Chris@16 27
Chris@16 28 // Must come last.
Chris@16 29 #include <boost/iostreams/detail/config/disable_warnings.hpp> // MSVC.
Chris@16 30
Chris@16 31 namespace boost { namespace iostreams { namespace detail {
Chris@16 32
Chris@16 33 // Used for simulated tag dispatch.
Chris@16 34 template<typename Traversal> struct range_adapter_impl;
Chris@16 35
Chris@16 36 //
Chris@16 37 // Template name: range_adapter
Chris@16 38 // Description: Device based on an instance of boost::iterator_range.
Chris@16 39 // Template parameters:
Chris@16 40 // Mode - A mode tag.
Chris@16 41 // Range - An instance of iterator_range.
Chris@16 42 //
Chris@16 43 template<typename Mode, typename Range>
Chris@16 44 class range_adapter {
Chris@16 45 private:
Chris@16 46 typedef typename Range::iterator iterator;
Chris@16 47 typedef boost::detail::iterator_traits<iterator> iter_traits;
Chris@16 48 typedef typename iter_traits::iterator_category iter_cat;
Chris@16 49 public:
Chris@16 50 typedef typename Range::value_type char_type;
Chris@16 51 struct category : Mode, device_tag { };
Chris@16 52 typedef typename
Chris@16 53 mpl::if_<
Chris@16 54 is_convertible<
Chris@16 55 iter_cat,
Chris@16 56 std::random_access_iterator_tag
Chris@16 57 >,
Chris@16 58 std::random_access_iterator_tag,
Chris@16 59 std::forward_iterator_tag
Chris@16 60 >::type tag;
Chris@16 61 typedef range_adapter_impl<tag> impl;
Chris@16 62
Chris@16 63 explicit range_adapter(const Range& rng);
Chris@16 64 range_adapter(iterator first, iterator last);
Chris@16 65 std::streamsize read(char_type* s, std::streamsize n);
Chris@16 66 std::streamsize write(const char_type* s, std::streamsize n);
Chris@16 67 std::streampos seek(stream_offset off, BOOST_IOS::seekdir way);
Chris@16 68 private:
Chris@16 69 iterator first_, cur_, last_;
Chris@16 70 };
Chris@16 71
Chris@16 72 //------------------Implementation of range_adapter---------------------------//
Chris@16 73
Chris@16 74 template<typename Mode, typename Range>
Chris@16 75 range_adapter<Mode, Range>::range_adapter(const Range& rng)
Chris@16 76 : first_(rng.begin()), cur_(rng.begin()), last_(rng.end()) { }
Chris@16 77
Chris@16 78 template<typename Mode, typename Range>
Chris@16 79 range_adapter<Mode, Range>::range_adapter(iterator first, iterator last)
Chris@16 80 : first_(first), cur_(first), last_(last) { }
Chris@16 81
Chris@16 82 template<typename Mode, typename Range>
Chris@16 83 inline std::streamsize range_adapter<Mode, Range>::read
Chris@16 84 (char_type* s, std::streamsize n)
Chris@16 85 { return impl::read(cur_, last_, s, n); }
Chris@16 86
Chris@16 87 template<typename Mode, typename Range>
Chris@16 88 inline std::streamsize range_adapter<Mode, Range>::write
Chris@16 89 (const char_type* s, std::streamsize n)
Chris@16 90 { return impl::write(cur_, last_, s, n); }
Chris@16 91
Chris@16 92
Chris@16 93 template<typename Mode, typename Range>
Chris@16 94 std::streampos range_adapter<Mode, Range>::seek
Chris@16 95 (stream_offset off, BOOST_IOS::seekdir way)
Chris@16 96 {
Chris@16 97 impl::seek(first_, cur_, last_, off, way);
Chris@16 98 return offset_to_position(cur_ - first_);
Chris@16 99 }
Chris@16 100
Chris@16 101 //------------------Implementation of range_adapter_impl----------------------//
Chris@16 102
Chris@16 103 template<>
Chris@16 104 struct range_adapter_impl<std::forward_iterator_tag> {
Chris@16 105 template<typename Iter, typename Ch>
Chris@16 106 static std::streamsize read
Chris@16 107 (Iter& cur, Iter& last, Ch* s,std::streamsize n)
Chris@16 108 {
Chris@16 109 std::streamsize rem = n; // No. of chars remaining.
Chris@16 110 while (cur != last && rem-- > 0) *s++ = *cur++;
Chris@16 111 return n - rem != 0 ? n - rem : -1;
Chris@16 112 }
Chris@16 113
Chris@16 114 template<typename Iter, typename Ch>
Chris@16 115 static std::streamsize write
Chris@16 116 (Iter& cur, Iter& last, const Ch* s, std::streamsize n)
Chris@16 117 {
Chris@16 118 while (cur != last && n-- > 0) *cur++ = *s++;
Chris@16 119 if (cur == last && n > 0)
Chris@16 120 boost::throw_exception(write_area_exhausted());
Chris@16 121 return n;
Chris@16 122 }
Chris@16 123 };
Chris@16 124
Chris@16 125 template<>
Chris@16 126 struct range_adapter_impl<std::random_access_iterator_tag> {
Chris@16 127 template<typename Iter, typename Ch>
Chris@16 128 static std::streamsize read
Chris@16 129 (Iter& cur, Iter& last, Ch* s,std::streamsize n)
Chris@16 130 {
Chris@16 131 std::streamsize result =
Chris@16 132 (std::min)(static_cast<std::streamsize>(last - cur), n);
Chris@16 133 if (result)
Chris@16 134 std::copy(cur, cur + result, s);
Chris@16 135 cur += result;
Chris@16 136 return result != 0 ? result : -1;
Chris@16 137 }
Chris@16 138
Chris@16 139 template<typename Iter, typename Ch>
Chris@16 140 static std::streamsize write
Chris@16 141 (Iter& cur, Iter& last, const Ch* s, std::streamsize n)
Chris@16 142 {
Chris@16 143 std::streamsize count =
Chris@16 144 (std::min)(static_cast<std::streamsize>(last - cur), n);
Chris@16 145 std::copy(s, s + count, cur);
Chris@16 146 cur += count;
Chris@16 147 if (count < n)
Chris@16 148 boost::throw_exception(write_area_exhausted());
Chris@16 149 return n;
Chris@16 150 }
Chris@16 151
Chris@16 152 template<typename Iter>
Chris@16 153 static void seek
Chris@16 154 ( Iter& first, Iter& cur, Iter& last, stream_offset off,
Chris@16 155 BOOST_IOS::seekdir way )
Chris@16 156 {
Chris@16 157 using namespace std;
Chris@16 158 switch (way) {
Chris@16 159 case BOOST_IOS::beg:
Chris@16 160 if (off > last - first || off < 0)
Chris@16 161 boost::throw_exception(bad_seek());
Chris@16 162 cur = first + off;
Chris@16 163 break;
Chris@16 164 case BOOST_IOS::cur:
Chris@16 165 {
Chris@16 166 std::ptrdiff_t newoff = cur - first + off;
Chris@16 167 if (newoff > last - first || newoff < 0)
Chris@16 168 boost::throw_exception(bad_seek());
Chris@16 169 cur += off;
Chris@16 170 break;
Chris@16 171 }
Chris@16 172 case BOOST_IOS::end:
Chris@16 173 if (last - first + off < 0 || off > 0)
Chris@16 174 boost::throw_exception(bad_seek());
Chris@16 175 cur = last + off;
Chris@16 176 break;
Chris@16 177 default:
Chris@16 178 BOOST_ASSERT(0);
Chris@16 179 }
Chris@16 180 }
Chris@16 181 };
Chris@16 182
Chris@16 183 } } } // End namespaces detail, iostreams, boost.
Chris@16 184
Chris@16 185 #include <boost/iostreams/detail/config/enable_warnings.hpp> // MSVC.
Chris@16 186
Chris@16 187 #endif // #ifndef BOOST_IOSTREAMS_DETAIL_RANGE_ADAPTER_HPP_INCLUDED //---------------//