| [12] | 1 | // (C) Copyright Jonathan Turkanis 2003. | 
|---|
 | 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | 
|---|
 | 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) | 
|---|
 | 4 |  | 
|---|
 | 5 | // See http://www.boost.org/libs/iostreams for documentation. | 
|---|
 | 6 |  | 
|---|
 | 7 | #ifndef BOOST_IOSTREAMS_PIPABLE_HPP_INCLUDED | 
|---|
 | 8 | #define BOOST_IOSTREAMS_PIPABLE_HPP_INCLUDED | 
|---|
 | 9 |  | 
|---|
 | 10 | #if defined(_MSC_VER) && (_MSC_VER >= 1020) | 
|---|
 | 11 | # pragma once | 
|---|
 | 12 | #endif | 
|---|
 | 13 |  | 
|---|
 | 14 | #include <boost/config.hpp> // BOOST_MSVC. | 
|---|
 | 15 | #include <boost/detail/workaround.hpp>            | 
|---|
 | 16 | #include <boost/iostreams/detail/template_params.hpp> | 
|---|
 | 17 | #include <boost/iostreams/traits.hpp> | 
|---|
 | 18 | #include <boost/mpl/bool.hpp> | 
|---|
 | 19 | #include <boost/preprocessor/punctuation/comma_if.hpp> | 
|---|
 | 20 | #include <boost/preprocessor/repetition/enum_params.hpp> | 
|---|
 | 21 | #include <boost/static_assert.hpp> | 
|---|
 | 22 | #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) | 
|---|
 | 23 | # include <boost/type_traits/is_base_and_derived.hpp> | 
|---|
 | 24 | #endif | 
|---|
 | 25 |  | 
|---|
 | 26 | #define BOOST_IOSTREAMS_PIPABLE(filter, arity) \ | 
|---|
 | 27 |     template< BOOST_PP_ENUM_PARAMS(arity, typename T) \ | 
|---|
 | 28 |               BOOST_PP_COMMA_IF(arity) typename Component> \ | 
|---|
 | 29 |     ::boost::iostreams::pipeline< \ | 
|---|
 | 30 |         ::boost::iostreams::detail::pipeline_segment< \ | 
|---|
 | 31 |             filter BOOST_IOSTREAMS_TEMPLATE_ARGS(arity, T) \ | 
|---|
 | 32 |         >, \ | 
|---|
 | 33 |         Component \ | 
|---|
 | 34 |     > operator|( const filter BOOST_IOSTREAMS_TEMPLATE_ARGS(arity, T)& f, \ | 
|---|
 | 35 |                  const Component& c ) \ | 
|---|
 | 36 |     { \ | 
|---|
 | 37 |         typedef ::boost::iostreams::detail::pipeline_segment< \ | 
|---|
 | 38 |                     filter BOOST_IOSTREAMS_TEMPLATE_ARGS(arity, T) \ | 
|---|
 | 39 |                 > segment; \ | 
|---|
 | 40 |         return ::boost::iostreams::pipeline<segment, Component> \ | 
|---|
 | 41 |                    (segment(f), c); \ | 
|---|
 | 42 |     } \ | 
|---|
 | 43 |     /**/ | 
|---|
 | 44 |  | 
|---|
 | 45 | namespace boost { namespace iostreams { | 
|---|
 | 46 |  | 
|---|
 | 47 | template<typename Pipeline, typename Component> | 
|---|
 | 48 | struct pipeline; | 
|---|
 | 49 |      | 
|---|
 | 50 | namespace detail { | 
|---|
 | 51 |  | 
|---|
 | 52 | #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)  | 
|---|
 | 53 |     struct pipeline_base { }; | 
|---|
 | 54 |  | 
|---|
 | 55 |     template<typename T> | 
|---|
 | 56 |     struct is_pipeline  | 
|---|
 | 57 |         : is_base_and_derived<pipeline_base, T> | 
|---|
 | 58 |         { }; | 
|---|
 | 59 | #endif  | 
|---|
 | 60 | #if BOOST_WORKAROUND(__BORLANDC__, < 0x600) | 
|---|
 | 61 |     template<typename T> | 
|---|
 | 62 |     struct is_pipeline : mpl::false_ { }; | 
|---|
 | 63 |  | 
|---|
 | 64 |     template<typename Pipeline, typename Component> | 
|---|
 | 65 |     struct is_pipeline< pipeline<Pipeline, Component> > : mpl::true_ { }; | 
|---|
 | 66 | #endif | 
|---|
 | 67 |  | 
|---|
 | 68 | template<typename Component> | 
|---|
 | 69 | class pipeline_segment  | 
|---|
 | 70 | #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) | 
|---|
 | 71 |     : pipeline_base  | 
|---|
 | 72 | #endif  | 
|---|
 | 73 | { | 
|---|
 | 74 | public: | 
|---|
 | 75 |     pipeline_segment(const Component& component)  | 
|---|
 | 76 |         : component_(component)  | 
|---|
 | 77 |         { } | 
|---|
 | 78 |     template<typename Fn> | 
|---|
 | 79 |     void for_each(Fn fn) const { fn(component_); } | 
|---|
 | 80 |     template<typename Chain> | 
|---|
 | 81 |     void push(Chain& chn) const { chn.push(component_); } | 
|---|
 | 82 | private: | 
|---|
 | 83 |     const Component& component_; | 
|---|
 | 84 | }; | 
|---|
 | 85 |  | 
|---|
 | 86 | } // End namespace detail. | 
|---|
 | 87 |                      | 
|---|
 | 88 | //------------------Definition of Pipeline------------------------------------// | 
|---|
 | 89 |  | 
|---|
 | 90 | template<typename Pipeline, typename Component> | 
|---|
 | 91 | struct pipeline : Pipeline { | 
|---|
 | 92 |     typedef Pipeline   pipeline_type; | 
|---|
 | 93 |     typedef Component  component_type; | 
|---|
 | 94 |     pipeline(const Pipeline& p, const Component& component) | 
|---|
 | 95 |         : Pipeline(p), component_(component) | 
|---|
 | 96 |         { } | 
|---|
 | 97 |     template<typename Fn> | 
|---|
 | 98 |     void for_each(Fn fn) const | 
|---|
 | 99 |     { | 
|---|
 | 100 |         Pipeline::for_each(fn); | 
|---|
 | 101 |         fn(component_); | 
|---|
 | 102 |     } | 
|---|
 | 103 |     template<typename Chain> | 
|---|
 | 104 |     void push(Chain& chn) const | 
|---|
 | 105 |     {  | 
|---|
 | 106 |         Pipeline::push(chn); | 
|---|
 | 107 |         chn.push(component_); | 
|---|
 | 108 |     } | 
|---|
 | 109 |     const Pipeline& tail() const { return *this; } | 
|---|
 | 110 |     const Component& head() const { return component_; } | 
|---|
 | 111 | private: | 
|---|
 | 112 |     const Component& component_; | 
|---|
 | 113 | }; | 
|---|
 | 114 |  | 
|---|
 | 115 | template<typename Pipeline, typename Filter, typename Component> | 
|---|
 | 116 | pipeline<pipeline<Pipeline, Filter>, Component> | 
|---|
 | 117 | operator|(const pipeline<Pipeline, Filter>& p, const Component& cmp) | 
|---|
 | 118 | { | 
|---|
 | 119 |     BOOST_STATIC_ASSERT(is_filter<Filter>::value); | 
|---|
 | 120 |     return pipeline<pipeline<Pipeline, Filter>, Component>(p, cmp); | 
|---|
 | 121 | } | 
|---|
 | 122 |  | 
|---|
 | 123 | } } // End namespaces iostreams, boost. | 
|---|
 | 124 |  | 
|---|
 | 125 | #endif // #ifndef BOOST_IOSTREAMS_PIPABLE_HPP_INCLUDED | 
|---|