| 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 | 
|---|