// (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_PIPABLE_HPP_INCLUDED | |
#define BOOST_IOSTREAMS_PIPABLE_HPP_INCLUDED | |
#if defined(_MSC_VER) && (_MSC_VER >= 1020) | |
# pragma once | |
#endif | |
#include <boost/config.hpp> // BOOST_MSVC. | |
#include <boost/detail/workaround.hpp> | |
#include <boost/iostreams/detail/template_params.hpp> | |
#include <boost/iostreams/traits.hpp> | |
#include <boost/mpl/bool.hpp> | |
#include <boost/preprocessor/punctuation/comma_if.hpp> | |
#include <boost/preprocessor/repetition/enum_params.hpp> | |
#include <boost/static_assert.hpp> | |
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) | |
# include <boost/type_traits/is_base_and_derived.hpp> | |
#endif | |
#define BOOST_IOSTREAMS_PIPABLE(filter, arity) \ | |
template< BOOST_PP_ENUM_PARAMS(arity, typename T) \ | |
BOOST_PP_COMMA_IF(arity) typename Component> \ | |
::boost::iostreams::pipeline< \ | |
::boost::iostreams::detail::pipeline_segment< \ | |
filter BOOST_IOSTREAMS_TEMPLATE_ARGS(arity, T) \ | |
>, \ | |
Component \ | |
> operator|( const filter BOOST_IOSTREAMS_TEMPLATE_ARGS(arity, T)& f, \ | |
const Component& c ) \ | |
{ \ | |
typedef ::boost::iostreams::detail::pipeline_segment< \ | |
filter BOOST_IOSTREAMS_TEMPLATE_ARGS(arity, T) \ | |
> segment; \ | |
return ::boost::iostreams::pipeline<segment, Component> \ | |
(segment(f), c); \ | |
} \ | |
/**/ | |
namespace boost { namespace iostreams { | |
template<typename Pipeline, typename Component> | |
struct pipeline; | |
namespace detail { | |
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) | |
struct pipeline_base { }; | |
template<typename T> | |
struct is_pipeline | |
: is_base_and_derived<pipeline_base, T> | |
{ }; | |
#endif | |
#if BOOST_WORKAROUND(__BORLANDC__, < 0x600) | |
template<typename T> | |
struct is_pipeline : mpl::false_ { }; | |
template<typename Pipeline, typename Component> | |
struct is_pipeline< pipeline<Pipeline, Component> > : mpl::true_ { }; | |
#endif | |
template<typename Component> | |
class pipeline_segment | |
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) | |
: pipeline_base | |
#endif | |
{ | |
public: | |
pipeline_segment(const Component& component) | |
: component_(component) | |
{ } | |
template<typename Fn> | |
void for_each(Fn fn) const { fn(component_); } | |
template<typename Chain> | |
void push(Chain& chn) const { chn.push(component_); } | |
private: | |
pipeline_segment operator=(const pipeline_segment&); | |
const Component& component_; | |
}; | |
} // End namespace detail. | |
//------------------Definition of Pipeline------------------------------------// | |
template<typename Pipeline, typename Component> | |
struct pipeline : Pipeline { | |
typedef Pipeline pipeline_type; | |
typedef Component component_type; | |
pipeline(const Pipeline& p, const Component& component) | |
: Pipeline(p), component_(component) | |
{ } | |
template<typename Fn> | |
void for_each(Fn fn) const | |
{ | |
Pipeline::for_each(fn); | |
fn(component_); | |
} | |
template<typename Chain> | |
void push(Chain& chn) const | |
{ | |
Pipeline::push(chn); | |
chn.push(component_); | |
} | |
const Pipeline& tail() const { return *this; } | |
const Component& head() const { return component_; } | |
private: | |
pipeline operator=(const pipeline&); | |
const Component& component_; | |
}; | |
template<typename Pipeline, typename Filter, typename Component> | |
pipeline<pipeline<Pipeline, Filter>, Component> | |
operator|(const pipeline<Pipeline, Filter>& p, const Component& cmp) | |
{ | |
BOOST_STATIC_ASSERT(is_filter<Filter>::value); | |
return pipeline<pipeline<Pipeline, Filter>, Component>(p, cmp); | |
} | |
} } // End namespaces iostreams, boost. | |
#endif // #ifndef BOOST_IOSTREAMS_PIPABLE_HPP_INCLUDED |