chain.hpp
来自「support vector clustering for vc++」· HPP 代码 · 共 564 行 · 第 1/2 页
HPP
564 行
// (C) Copyright Jonathan Turkanis 2003.
// 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_CHAIN_HPP_INCLUDED
#define BOOST_IOSTREAMS_DETAIL_CHAIN_HPP_INCLUDED
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <algorithm> // for_each.
#include <cassert>
#include <exception>
#include <functional> // unary_function.
#include <iterator> // advance.
#include <list>
#include <memory> // allocator, auto_ptr.
#include <typeinfo>
#include <stdexcept> // logic_error, out_of_range.
#include <boost/checked_delete.hpp>
#include <boost/config.hpp> // BOOST_MSVC, template friends,
#include <boost/detail/workaround.hpp> // BOOST_NESTED_TEMPLATE
#include <boost/iostreams/constants.hpp>
#include <boost/iostreams/detail/access_control.hpp>
#include <boost/iostreams/detail/char_traits.hpp>
#include <boost/iostreams/detail/push.hpp>
#include <boost/iostreams/detail/streambuf.hpp> // pubsync.
#include <boost/iostreams/detail/wrap_unwrap.hpp>
#include <boost/iostreams/device/null.hpp>
#include <boost/iostreams/positioning.hpp>
#include <boost/iostreams/traits.hpp> // is_filter.
#include <boost/iostreams/stream_buffer.hpp>
#include <boost/next_prior.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type.hpp>
#if BOOST_WORKAROUND(BOOST_MSVC, < 1310)
# include <boost/mpl/int.hpp>
#endif
// Sometimes type_info objects must be compared by name. Borrowed from
// Boost.Python and Boost.Function.
#if (defined(__GNUC__) && __GNUC__ >= 3) || \
defined(_AIX) || \
(defined(__sgi) && defined(__host_mips)) || \
(defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC)) \
/**/
# include <cstring>
# define BOOST_IOSTREAMS_COMPARE_TYPE_ID(X,Y) \
(std::strcmp((X).name(),(Y).name()) == 0)
#else
# define BOOST_IOSTREAMS_COMPARE_TYPE_ID(X,Y) ((X)==(Y))
#endif
// Deprecated
#define BOOST_IOSTREAMS_COMPONENT_TYPE(chain, index) \
chain.component_type( index ) \
/**/
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1310)
# define BOOST_IOSTREAMS_COMPONENT(chain, index, target) \
chain.component< target >( index ) \
/**/
#else
# define BOOST_IOSTREAMS_COMPONENT(chain, index, target) \
chain.component( index, ::boost::type< target >() ) \
/**/
#endif
namespace boost { namespace iostreams {
//--------------Definition of chain and wchain--------------------------------//
namespace detail {
template<typename Chain> class chain_client;
//
// Concept name: Chain.
// Description: Represents a chain of stream buffers which provides access
// to the first buffer in the chain and send notifications when the
// streambufs are added to or removed from chain.
// Refines: Closable device with mode equal to typename Chain::mode.
// Models: chain, converting_chain.
// Example:
//
// class chain {
// public:
// typedef xxx chain_type;
// typedef xxx client_type;
// typedef xxx mode;
// bool is_complete() const; // Ready for i/o.
// template<typename T>
// void push( const T& t, // Adds a stream buffer to
// streamsize, // chain, based on t, with
// streamsize ); // given buffer and putback
// // buffer sizes. Pass -1 to
// // request default size.
// protected:
// void register_client(client_type* client); // Associate client.
// void notify(); // Notify client.
// };
//
//
// Description: Represents a chain of filters with an optional device at the
// end.
// Template parameters:
// Self - A class deriving from the current instantiation of this template.
// This is an example of the Curiously Recurring Template Pattern.
// Ch - The character type.
// Tr - The character traits type.
// Alloc - The allocator type.
// Mode - A mode tag.
//
template<typename Self, typename Ch, typename Tr, typename Alloc, typename Mode>
class chain_base {
public:
typedef Ch char_type;
BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr)
typedef Alloc allocator_type;
typedef Mode mode;
struct category
: Mode,
device_tag
{ };
typedef chain_client<Self> client_type;
friend class chain_client<Self>;
private:
typedef linked_streambuf<Ch> streambuf_type;
typedef std::list<streambuf_type*> list_type;
typedef chain_base<Self, Ch, Tr, Alloc, Mode> my_type;
protected:
chain_base() : pimpl_(new chain_impl) { }
chain_base(const chain_base& rhs): pimpl_(rhs.pimpl_) { }
public:
//----------Buffer sizing-------------------------------------------------//
// Sets the size of the buffer created for the devices to be added to this
// chain. Does not affect the size of the buffer for devices already
// added.
void set_device_buffer_size(int n) { pimpl_->device_buffer_size_ = n; }
// Sets the size of the buffer created for the filters to be added
// to this chain. Does not affect the size of the buffer for filters already
// added.
void set_filter_buffer_size(int n) { pimpl_->filter_buffer_size_ = n; }
// Sets the size of the putback buffer for filters and devices to be added
// to this chain. Does not affect the size of the buffer for filters or
// devices already added.
void set_pback_size(int n) { pimpl_->pback_size_ = n; }
//----------Device interface----------------------------------------------//
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);
//----------Direct component access---------------------------------------//
const std::type_info& component_type(int n) const
{
if (static_cast<size_type>(n) >= size())
throw std::out_of_range("bad chain offset");
return (*boost::next(list().begin(), n))->component_type();
}
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1310)
// Deprecated.
template<int N>
const std::type_info& component_type() const { return component_type(N); }
template<typename T>
T* component(int n) const { return component(n, boost::type<T>()); }
// Deprecated.
template<int N, typename T>
T* component() const { return component<T>(N); }
#endif
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1310)
private:
#endif
template<typename T>
T* component(int n, boost::type<T>) const
{
if (static_cast<size_type>(n) >= size())
throw std::out_of_range("bad chain offset");
streambuf_type* link = *boost::next(list().begin(), n);
if (BOOST_IOSTREAMS_COMPARE_TYPE_ID(link->component_type(), typeid(T)))
return static_cast<T*>(link->component_impl());
else
return 0;
}
public:
//----------Container-like interface--------------------------------------//
typedef typename list_type::size_type size_type;
streambuf_type& front() { return *list().front(); }
BOOST_IOSTREAMS_DEFINE_PUSH(push, mode, char_type, push_impl)
void pop();
bool empty() const { return list().empty(); }
size_type size() const { return list().size(); }
void reset();
//----------Additional i/o functions--------------------------------------//
// Returns true if this chain is non-empty and its final link
// is a source or sink, i.e., if it is ready to perform i/o.
bool is_complete() const;
bool auto_close() const;
void set_auto_close(bool close);
bool sync() { return front().BOOST_IOSTREAMS_PUBSYNC() != -1; }
bool strict_sync();
private:
template<typename T>
void push_impl(const T& t, int buffer_size = -1, int pback_size = -1)
{
typedef typename iostreams::category_of<T>::type category;
typedef typename unwrap_ios<T>::type policy_type;
typedef stream_buffer<
policy_type,
BOOST_IOSTREAMS_CHAR_TRAITS(char_type),
Alloc, Mode
> facade_type;
BOOST_STATIC_ASSERT((is_convertible<category, Mode>::value));
if (is_complete())
throw std::logic_error("chain complete");
streambuf_type* prev = !empty() ? list().back() : 0;
buffer_size =
buffer_size != -1 ?
buffer_size :
iostreams::optimal_buffer_size(t);
pback_size =
pback_size != -1 ?
pback_size :
pimpl_->pback_size_;
std::auto_ptr<facade_type>
buf(new facade_type(t, buffer_size, pback_size));
list().push_back(buf.get());
buf.release();
if (is_device<policy_type>::value)
pimpl_->flags_ |= f_complete | f_open;
if (prev) prev->set_next(list().back());
notify();
}
list_type& list() { return pimpl_->links_; }
const list_type& list() const { return pimpl_->links_; }
void register_client(client_type* client) { pimpl_->client_ = client; }
void notify() { if (pimpl_->client_) pimpl_->client_->notify(); }
//----------Nested classes------------------------------------------------//
static void close(streambuf_type* b, BOOST_IOS::openmode m)
{
if (m & BOOST_IOS::out)
b->BOOST_IOSTREAMS_PUBSYNC();
b->close(m);
}
static void set_next(streambuf_type* b, streambuf_type* next)
{ b->set_next(next); }
static void set_auto_close(streambuf_type* b, bool close)
{ b->set_auto_close(close); }
struct closer : public std::unary_function<streambuf_type*, void> {
closer(BOOST_IOS::openmode m) : mode_(m) { }
void operator() (streambuf_type* b)
{
close(b, mode_);
}
BOOST_IOS::openmode mode_;
};
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?