range_adapter.hpp

来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 184 行

HPP
184
字号
// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)// (C) Copyright 2003-2007 Jonathan Turkanis// 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.)// See http://www.boost.org/libs/iostreams for documentation.#ifndef BOOST_IOSTREAMS_DETAIL_RANGE_ADAPTER_HPP_INCLUDED#define BOOST_IOSTREAMS_DETAIL_RANGE_ADAPTER_HPP_INCLUDED#if defined(_MSC_VER) && (_MSC_VER >= 1020)# pragma once#endif              #include <algorithm>                             // min.#include <cassert>#include <cstddef>                               // ptrdiff_t.#include <iosfwd>                                // streamsize, streamoff.#include <boost/detail/iterator.hpp>             // boost::iterator_traits.#include <boost/iostreams/categories.hpp>#include <boost/iostreams/detail/error.hpp>#include <boost/iostreams/positioning.hpp>#include <boost/mpl/if.hpp>#include <boost/type_traits/is_convertible.hpp>#include <boost/utility/enable_if.hpp>// Must come last.#include <boost/iostreams/detail/config/disable_warnings.hpp>  // MSVC.namespace boost { namespace iostreams { namespace detail {// Used for simulated tag dispatch.template<typename Traversal> struct range_adapter_impl;//// Template name: range_adapter// Description: Device based on an instance of boost::iterator_range.// Template paramters://     Mode - A mode tag.//     Range - An instance of iterator_range.//template<typename Mode, typename Range>class range_adapter {private:    typedef typename Range::iterator                  iterator;    typedef boost::detail::iterator_traits<iterator>  iter_traits;    typedef typename iter_traits::iterator_category   iter_cat;public:    typedef typename Range::value_type                char_type;    struct category : Mode, device_tag { };    typedef typename            mpl::if_<                is_convertible<                    iter_cat,                    std::random_access_iterator_tag                >,                std::random_access_iterator_tag,                std::forward_iterator_tag            >::type                                   tag;    typedef range_adapter_impl<tag>                   impl;    explicit range_adapter(const Range& rng);    range_adapter(iterator first, iterator last);    std::streamsize read(char_type* s, std::streamsize n);    std::streamsize write(const char_type* s, std::streamsize n);    std::streampos seek(stream_offset off, BOOST_IOS::seekdir way);private:    iterator first_, cur_, last_;};//------------------Implementation of range_adapter---------------------------//template<typename Mode, typename Range>range_adapter<Mode, Range>::range_adapter(const Range& rng)    : first_(rng.begin()), cur_(rng.begin()), last_(rng.end()) { }template<typename Mode, typename Range>range_adapter<Mode, Range>::range_adapter(iterator first, iterator last)    : first_(first), cur_(first), last_(last) { }template<typename Mode, typename Range>inline std::streamsize range_adapter<Mode, Range>::read    (char_type* s, std::streamsize n){ return impl::read(cur_, last_, s, n); }template<typename Mode, typename Range>inline std::streamsize range_adapter<Mode, Range>::write    (const char_type* s, std::streamsize n){ return impl::write(cur_, last_, s, n); }template<typename Mode, typename Range>std::streampos range_adapter<Mode, Range>::seek    (stream_offset off, BOOST_IOS::seekdir way){     impl::seek(first_, cur_, last_, off, way);     return offset_to_position(cur_ - first_);}//------------------Implementation of range_adapter_impl----------------------//template<>struct range_adapter_impl<std::forward_iterator_tag> {    template<typename Iter, typename Ch>    static std::streamsize read        (Iter& cur, Iter& last, Ch* s,std::streamsize n)    {        std::streamsize rem = n; // No. of chars remaining.        while (cur != last && rem-- > 0) *s++ = *cur++;        return n - rem != 0 ? n - rem : -1;    }    template<typename Iter, typename Ch>    static std::streamsize write        (Iter& cur, Iter& last, const Ch* s, std::streamsize n)    {        while (cur != last && n-- > 0) *cur++ = *s++;        if (cur == last && n > 0)            throw write_area_exhausted();        return n;    }};template<>struct range_adapter_impl<std::random_access_iterator_tag> {    template<typename Iter, typename Ch>    static std::streamsize read        (Iter& cur, Iter& last, Ch* s,std::streamsize n)    {        std::streamsize result =             (std::min)(static_cast<std::streamsize>(last - cur), n);        if (result)            std::copy(cur, cur + result, s);        cur += result;        return result != 0 ? result : -1;    }    template<typename Iter, typename Ch>    static std::streamsize write        (Iter& cur, Iter& last, const Ch* s, std::streamsize n)    {        std::streamsize count =            (std::min)(static_cast<std::streamsize>(last - cur), n);        std::copy(s, s + count, cur);        cur += count;        if (count < n)             throw write_area_exhausted();        return n;    }    template<typename Iter>    static void seek        ( Iter& first, Iter& cur, Iter& last, stream_offset off,          BOOST_IOS::seekdir way )    {        using namespace std;        switch (way) {        case BOOST_IOS::beg:            if (off > last - first || off < 0) throw bad_seek();            cur = first + off;            break;        case BOOST_IOS::cur:            {                std::ptrdiff_t newoff = cur - first + off;                if (newoff > last - first || newoff < 0) throw bad_seek();                cur += off;                break;            }        case BOOST_IOS::end:            if (last - first + off < 0 || off > 0) throw bad_seek();            cur = last + off;            break;        default:            assert(0);        }    }};} } } // End namespaces detail, iostreams, boost.#include <boost/iostreams/detail/config/enable_warnings.hpp>  // MSVC.#endif // #ifndef BOOST_IOSTREAMS_DETAIL_RANGE_ADAPTER_HPP_INCLUDED //---------------//

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?