pipeline.hpp 3.6 KB

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