close.hpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
  2. // (C) Copyright 2005-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. namespace boost { namespace iostreams {
  7. namespace detail {
  8. template<typename T>
  9. struct close_impl;
  10. } // End namespace detail.
  11. template<typename T>
  12. void close(T& t) { detail::close_all(t); }
  13. template<typename T>
  14. void close(T& t, BOOST_IOS::openmode which)
  15. {
  16. typedef typename detail::unwrapped_type<T>::type unwrapped;
  17. detail::close_impl<T>::inner<unwrapped>::close(detail::unwrap(t), which);
  18. }
  19. template<typename T, typename Sink>
  20. void close(T& t, Sink& snk, BOOST_IOS::openmode which)
  21. {
  22. typedef typename detail::unwrapped_type<T>::type unwrapped;
  23. detail::close_impl<T>::inner<unwrapped>::close(detail::unwrap(t), snk, which);
  24. }
  25. namespace detail {
  26. //------------------Definition of close_impl----------------------------------//
  27. template<typename T>
  28. struct close_tag {
  29. typedef typename category_of<T>::type category;
  30. typedef typename
  31. mpl::eval_if<
  32. is_convertible<category, closable_tag>,
  33. mpl::if_<
  34. mpl::or_<
  35. is_convertible<category, two_sequence>,
  36. is_convertible<category, dual_use>
  37. >,
  38. two_sequence,
  39. closable_tag
  40. >,
  41. mpl::identity<any_tag>
  42. >::type type;
  43. };
  44. template<typename T>
  45. struct close_impl
  46. : mpl::if_<
  47. is_custom<T>,
  48. operations<T>,
  49. close_impl<BOOST_DEDUCED_TYPENAME close_tag<T>::type>
  50. >::type
  51. { };
  52. template<>
  53. struct close_impl<any_tag> {
  54. template<typename T>
  55. struct inner {
  56. static void close(T& t, BOOST_IOS::openmode which)
  57. {
  58. if (which == BOOST_IOS::out)
  59. iostreams::flush(t);
  60. }
  61. template<typename Sink>
  62. static void close(T& t, Sink& snk, BOOST_IOS::openmode which)
  63. {
  64. if (which == BOOST_IOS::out) {
  65. non_blocking_adapter<Sink> nb(snk);
  66. iostreams::flush(t, nb);
  67. }
  68. }
  69. };
  70. };
  71. template<>
  72. struct close_impl<closable_tag> {
  73. template<typename T>
  74. struct inner {
  75. static void close(T& t, BOOST_IOS::openmode which)
  76. {
  77. typedef typename category_of<T>::type category;
  78. const bool in = is_convertible<category, input>::value &&
  79. !is_convertible<category, output>::value;
  80. if (in == (which == BOOST_IOS::in))
  81. t.close();
  82. }
  83. template<typename Sink>
  84. static void close(T& t, Sink& snk, BOOST_IOS::openmode which)
  85. {
  86. typedef typename category_of<T>::type category;
  87. const bool in = is_convertible<category, input>::value &&
  88. !is_convertible<category, output>::value;
  89. if (in == (which == BOOST_IOS::in)) {
  90. non_blocking_adapter<Sink> nb(snk);
  91. t.close(nb);
  92. }
  93. }
  94. };
  95. };
  96. template<>
  97. struct close_impl<two_sequence> {
  98. template<typename T>
  99. struct inner {
  100. static void close(T& t, BOOST_IOS::openmode which) { t.close(which); }
  101. template<typename Sink>
  102. static void close(T& t, Sink& snk, BOOST_IOS::openmode which)
  103. {
  104. non_blocking_adapter<Sink> nb(snk);
  105. t.close(nb, which);
  106. }
  107. };
  108. };
  109. } // End namespace detail.
  110. } } // End namespaces iostreams, boost.