Boost logo

Boost-Commit :

From: technews_at_[hidden]
Date: 2008-01-06 13:32:06


Author: turkanis
Date: 2008-01-06 13:32:05 EST (Sun, 06 Jan 2008)
New Revision: 42544
URL: http://svn.boost.org/trac/boost/changeset/42544

Log:
copy.hpp:

    fix for Visual Age: std::min was passed arguments of different types; replaced std:: min with conditional

detail/streambuf/indirect_streambuf.hpp:

    removed trailing comma in enum definition

test/combine_test.cpp:
test/symmetric_filter_test.cpp:
test/compose_test.cpp:
test/close_test.cpp:
test/invert_test.cpp:
test/tee_test.cpp:
test/restrict_test.cpp:
test/Jamfile.v2:

    moved tests for close() into the test files for various adapters
Added:
   trunk/libs/iostreams/test/combine_test.cpp
      - copied unchanged from r42543, /branches/iostreams_dev/libs/iostreams/test/combine_test.cpp
Text files modified:
   trunk/boost/iostreams/copy.hpp | 7
   trunk/boost/iostreams/detail/streambuf/indirect_streambuf.hpp | 2
   trunk/libs/iostreams/test/Jamfile.v2 | 1
   trunk/libs/iostreams/test/close_test.cpp | 909 ---------------------------------------
   trunk/libs/iostreams/test/compose_test.cpp | 391 ++++++++++++++++
   trunk/libs/iostreams/test/invert_test.cpp | 32 +
   trunk/libs/iostreams/test/restrict_test.cpp | 117 +++++
   trunk/libs/iostreams/test/symmetric_filter_test.cpp | 43 +
   trunk/libs/iostreams/test/tee_test.cpp | 228 +++++++++
   9 files changed, 801 insertions(+), 929 deletions(-)

Modified: trunk/boost/iostreams/copy.hpp
==============================================================================
--- trunk/boost/iostreams/copy.hpp (original)
+++ trunk/boost/iostreams/copy.hpp 2008-01-06 13:32:05 EST (Sun, 06 Jan 2008)
@@ -94,19 +94,20 @@
                            std::streamsize buffer_size,
                            mpl::false_, mpl::true_ )
 {
- using namespace std;
     typedef typename char_type_of<Source>::type char_type;
     typedef std::pair<char_type*, char_type*> pair_type;
     detail::basic_buffer<char_type> buf(buffer_size);
     pair_type p = snk.output_sequence();
     std::streamsize total = 0;
- ptrdiff_t capacity = p.second - p.first;
+ std::ptrdiff_t capacity = p.second - p.first;
     while (true) {
         std::streamsize amt =
             iostreams::read(
                 src,
                 buf.data(),
- (std::min)(buffer_size, capacity - total)
+ buffer_size < capacity - total ?
+ buffer_size :
+ static_cast<std::streamsize>(capacity - total)
             );
         if (amt == -1)
             break;

Modified: trunk/boost/iostreams/detail/streambuf/indirect_streambuf.hpp
==============================================================================
--- trunk/boost/iostreams/detail/streambuf/indirect_streambuf.hpp (original)
+++ trunk/boost/iostreams/detail/streambuf/indirect_streambuf.hpp 2008-01-06 13:32:05 EST (Sun, 06 Jan 2008)
@@ -124,7 +124,7 @@
     enum flag_type {
         f_open = 1,
         f_output_buffered = f_open << 1,
- f_auto_close = f_output_buffered << 1,
+ f_auto_close = f_output_buffered << 1
     };
 
     optional<wrapper> storage_;

Modified: trunk/libs/iostreams/test/Jamfile.v2
==============================================================================
--- trunk/libs/iostreams/test/Jamfile.v2 (original)
+++ trunk/libs/iostreams/test/Jamfile.v2 2008-01-06 13:32:05 EST (Sun, 06 Jan 2008)
@@ -39,6 +39,7 @@
           [ test-iostreams
                 code_converter_test.cpp
                 detail/utf8_codecvt_facet.cpp ]
+ [ test-iostreams combine_test.cpp ]
           [ test-iostreams compose_test.cpp ]
           [ test-iostreams component_access_test.cpp ]
           [ test-iostreams copy_test.cpp ]

Modified: trunk/libs/iostreams/test/close_test.cpp
==============================================================================
--- trunk/libs/iostreams/test/close_test.cpp (original)
+++ trunk/libs/iostreams/test/close_test.cpp 2008-01-06 13:32:05 EST (Sun, 06 Jan 2008)
@@ -6,7 +6,7 @@
  *
  * Verifies that the close() member functions of filters and devices
  * are called with the correct arguments in the correct order when
- * they are combined using chains or adapters.
+ * used with chains and streams.
  *
  * File: libs/iostreams/test/close_test.cpp
  * Date: Sun Dec 09 16:12:23 MST 2007
@@ -506,905 +506,6 @@
     }
 }
 
-void combine_test()
-{
- // Combine a source and a sink
- {
- operation_sequence seq;
- chain<bidirectional> ch;
- ch.push(
- io::combine(
- closable_device<input>(seq.new_operation(1)),
- closable_device<output>(seq.new_operation(2))
- )
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Combine two bidirectional devices
- {
- operation_sequence seq;
- chain<bidirectional> ch;
- ch.push(
- io::combine(
- closable_device<bidirectional>(
- seq.new_operation(1),
- seq.new_operation(2)
- ),
- closable_device<bidirectional>(
- seq.new_operation(3),
- seq.new_operation(4)
- )
- )
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Combine two seekable devices
- {
- operation_sequence seq;
- chain<bidirectional> ch;
- ch.push(
- io::combine(
- closable_device<seekable>(seq.new_operation(1)),
- closable_device<seekable>(seq.new_operation(2))
- )
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Combine an input filter and an output filter
- {
- operation_sequence seq;
- chain<bidirectional> ch;
- ch.push(
- io::combine(
- closable_filter<input>(seq.new_operation(2)),
- closable_filter<output>(seq.new_operation(3))
- )
- );
- ch.push(
- closable_device<bidirectional>(
- seq.new_operation(1),
- seq.new_operation(4)
- )
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Combine two bidirectional filters
- {
- operation_sequence seq;
- chain<bidirectional> ch;
- ch.push(
- io::combine(
- closable_filter<bidirectional>(
- seq.new_operation(2),
- seq.new_operation(3)
- ),
- closable_filter<bidirectional>(
- seq.new_operation(4),
- seq.new_operation(5)
- )
- )
- );
- ch.push(
- closable_device<bidirectional>(
- seq.new_operation(1),
- seq.new_operation(6)
- )
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Combine two seekable filters
- {
- operation_sequence seq;
- chain<bidirectional> ch;
- ch.push(
- io::combine(
- closable_filter<seekable>(seq.new_operation(2)),
- closable_filter<seekable>(seq.new_operation(3))
- )
- );
- ch.push(
- closable_device<bidirectional>(
- seq.new_operation(1),
- seq.new_operation(4)
- )
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Combine two dual-use filters
- {
- operation_sequence seq;
- chain<bidirectional> ch;
- ch.push(
- io::combine(
- closable_filter<dual_use>(
- seq.new_operation(2),
- seq.new_operation(3)
- ),
- closable_filter<dual_use>(
- seq.new_operation(4),
- seq.new_operation(5)
- )
- )
- );
- ch.push(
- closable_device<bidirectional>(
- seq.new_operation(1),
- seq.new_operation(6)
- )
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-}
-
-void composite_device_test()
-{
- // Compose an input filter with a source
- {
- operation_sequence seq;
- chain<input> ch;
- ch.push(
- io::compose(
- closable_filter<input>(seq.new_operation(2)),
- closable_device<input>(seq.new_operation(1))
- )
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Compose a bidirectional filter with a source
- {
- operation_sequence seq;
- chain<input> ch;
- ch.push(
- io::compose(
- closable_filter<bidirectional>(
- seq.new_operation(2),
- seq.new_operation(3)
- ),
- closable_device<input>(seq.new_operation(1))
- )
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Compose a seekable filter with a source
- {
- operation_sequence seq;
- chain<input> ch;
- ch.push(
- io::compose(
- closable_filter<seekable>(seq.new_operation(2)),
- closable_device<input>(seq.new_operation(1))
- )
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Compose a dual-use filter with a source
- {
- operation_sequence seq;
- chain<input> ch;
- ch.push(
- io::compose(
- closable_filter<dual_use>(
- seq.new_operation(2),
- seq.new_operation(3)
- ),
- closable_device<input>(seq.new_operation(1))
- )
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Compose an output filter with a sink
- {
- operation_sequence seq;
- chain<output> ch;
- ch.push(
- io::compose(
- closable_filter<output>(seq.new_operation(1)),
- closable_device<output>(seq.new_operation(2))
- )
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Compose a bidirectional filter with a sink
- {
- operation_sequence seq;
- chain<output> ch;
- ch.push(
- io::compose(
- closable_filter<bidirectional>(
- seq.new_operation(1),
- seq.new_operation(2)
- ),
- closable_device<output>(seq.new_operation(3))
- )
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Compose a seekable filter with a sink
- {
- operation_sequence seq;
- chain<output> ch;
- ch.push(
- io::compose(
- closable_filter<seekable>(seq.new_operation(1)),
- closable_device<output>(seq.new_operation(2))
- )
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Compose a dual-use filter with a sink
- {
- operation_sequence seq;
- chain<output> ch;
- ch.push(
- io::compose(
- closable_filter<dual_use>(
- seq.new_operation(1),
- seq.new_operation(2)
- ),
- closable_device<output>(seq.new_operation(3))
- )
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Compose a bidirectional filter with a bidirectional device
- {
- operation_sequence seq;
- chain<bidirectional> ch;
- ch.push(
- io::compose(
- closable_filter<bidirectional>(
- seq.new_operation(2),
- seq.new_operation(3)
- ),
- closable_device<bidirectional>(
- seq.new_operation(1),
- seq.new_operation(4)
- )
- )
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Compose a seekable filter with a seekable device
- {
- operation_sequence seq;
- chain<seekable> ch;
- ch.push(
- io::compose(
- closable_filter<seekable>(seq.new_operation(1)),
- closable_device<seekable>(seq.new_operation(2))
- )
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-}
-
-void composite_filter_test()
-{
- // Compose two input filters
- {
- operation_sequence seq;
- chain<input> ch;
- ch.push(
- io::compose(
- closable_filter<input>(seq.new_operation(3)),
- closable_filter<input>(seq.new_operation(2))
- )
- );
- ch.push(closable_device<input>(seq.new_operation(1)));
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Compose a bidirectional filter with an input filter
- {
- operation_sequence seq;
- chain<input> ch;
- ch.push(
- io::compose(
- closable_filter<bidirectional>(
- seq.new_operation(3),
- seq.new_operation(4)
- ),
- closable_filter<input>(seq.new_operation(2))
- )
- );
- ch.push(closable_device<input>(seq.new_operation(1)));
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_MESSAGE(seq.is_success(), seq.message());
- }
-
- // Compose a seekable filter with an input filter
- {
- operation_sequence seq;
- chain<input> ch;
- ch.push(
- io::compose(
- closable_filter<seekable>(seq.new_operation(3)),
- closable_filter<input>(seq.new_operation(2))
- )
- );
- ch.push(closable_device<input>(seq.new_operation(1)));
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Compose a dual-use filter with an input filter
- {
- operation_sequence seq;
- chain<input> ch;
- ch.push(
- io::compose(
- closable_filter<dual_use>(
- seq.new_operation(3),
- seq.new_operation(4)
- ),
- closable_filter<input>(seq.new_operation(2))
- )
- );
- ch.push(closable_device<input>(seq.new_operation(1)));
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Compose two output filters
- {
- operation_sequence seq;
- chain<output> ch;
- ch.push(
- io::compose(
- closable_filter<output>(seq.new_operation(1)),
- closable_filter<output>(seq.new_operation(2))
- )
- );
- ch.push(closable_device<output>(seq.new_operation(3)));
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Compose a bidirectional filter with an output filter
- {
- operation_sequence seq;
- chain<output> ch;
- ch.push(
- io::compose(
- closable_filter<bidirectional>(
- seq.new_operation(1),
- seq.new_operation(2)
- ),
- closable_filter<output>(seq.new_operation(3))
- )
- );
- ch.push(closable_device<output>(seq.new_operation(4)));
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Compose a seekable filter with an output filter
- {
- operation_sequence seq;
- chain<output> ch;
- ch.push(
- io::compose(
- closable_filter<seekable>(seq.new_operation(1)),
- closable_filter<output>(seq.new_operation(2))
- )
- );
- ch.push(closable_device<output>(seq.new_operation(3)));
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Compose a dual-use filter with an output filter
- {
- operation_sequence seq;
- chain<output> ch;
- ch.push(
- io::compose(
- closable_filter<dual_use>(
- seq.new_operation(1),
- seq.new_operation(2)
- ),
- closable_filter<output>(seq.new_operation(3))
- )
- );
- ch.push(closable_device<output>(seq.new_operation(4)));
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Compose two bidirectional filters
- {
- operation_sequence seq;
- chain<bidirectional> ch;
- ch.push(
- io::compose(
- closable_filter<bidirectional>(
- seq.new_operation(3),
- seq.new_operation(4)
- ),
- closable_filter<bidirectional>(
- seq.new_operation(2),
- seq.new_operation(5)
- )
- )
- );
- ch.push(
- closable_device<bidirectional>(
- seq.new_operation(1),
- seq.new_operation(6)
- )
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Compose two seekable filters
- {
- operation_sequence seq;
- chain<seekable> ch;
- ch.push(
- io::compose(
- closable_filter<seekable>(seq.new_operation(1)),
- closable_filter<seekable>(seq.new_operation(2))
- )
- );
- ch.push(closable_device<seekable>(seq.new_operation(3)));
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Compose two dual-use filters for input
- {
- operation_sequence seq;
- chain<input> ch;
- ch.push(
- io::compose(
- closable_filter<dual_use>(
- seq.new_operation(3),
- seq.new_operation(4)
- ),
- closable_filter<dual_use>(
- seq.new_operation(2),
- seq.new_operation(5)
- )
- )
- );
- ch.push(closable_device<input>(seq.new_operation(1)));
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Compose two dual-use filters for output
- {
- operation_sequence seq;
- chain<output> ch;
- ch.push(
- io::compose(
- closable_filter<dual_use>(
- seq.new_operation(2),
- seq.new_operation(3)
- ),
- closable_filter<dual_use>(
- seq.new_operation(1),
- seq.new_operation(4)
- )
- )
- );
- ch.push(closable_device<output>(seq.new_operation(5)));
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-}
-
-void invert_test()
-{
- // Invert an output filter
- {
- operation_sequence seq;
- chain<input> ch;
- ch.push(io::invert(closable_filter<output>(seq.new_operation(2))));
- ch.push(closable_device<input>(seq.new_operation(1)));
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Invert an input filter
- {
- operation_sequence seq;
- chain<output> ch;
- ch.push(io::invert(closable_filter<input>(seq.new_operation(1))));
- ch.push(closable_device<output>(seq.new_operation(2)));
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-}
-
-void restrict_test()
-{
- // Restrict a source
- {
- operation_sequence seq;
- chain<input> ch;
- ch.push(io::restrict(closable_device<input>(seq.new_operation(1)), 0));
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Restrict a seekable device
- {
- operation_sequence seq;
- chain<seekable> ch;
- ch.push(
- io::restrict(closable_device<seekable>(seq.new_operation(1)), 0)
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Restrict a direct source
- {
- operation_sequence seq;
- chain<input> ch;
- ch.push(
- io::restrict(closable_device<direct_input>(seq.new_operation(1)), 0)
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Restrict a direct seekable device
- {
- operation_sequence seq;
- chain<seekable> ch;
- ch.push(
- io::restrict(
- closable_device<direct_seekable>(seq.new_operation(1)),
- 0
- )
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Restrict an input filter
- {
- operation_sequence seq;
- chain<input> ch;
- ch.push(io::restrict(closable_filter<input>(seq.new_operation(2)), 0));
- ch.push(closable_device<input>(seq.new_operation(1)));
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Restrict a seekable filter
- {
- operation_sequence seq;
- chain<seekable> ch;
- ch.push(
- io::restrict(closable_filter<seekable>(seq.new_operation(1)), 0)
- );
- ch.push(closable_device<seekable>(seq.new_operation(2)));
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Restrict a dual_use filter for input
- {
- operation_sequence seq;
- chain<input> ch;
- ch.push(
- io::restrict(
- closable_filter<dual_use>(
- seq.new_operation(2),
- seq.new_operation(3)
- ),
- 0
- )
- );
- ch.push(closable_device<input>(seq.new_operation(1)));
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Restrict a dual_use filter for output
- {
- operation_sequence seq;
- chain<output> ch;
- ch.push(
- io::restrict(
- closable_filter<dual_use>(
- seq.new_operation(1),
- seq.new_operation(2)
- ),
- 0
- )
- );
- ch.push(closable_device<output>(seq.new_operation(3)));
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-}
-
-void symmetric_filter_test()
-{
- // Test input
- {
- operation_sequence seq;
- chain<input> ch;
- ch.push(
- io::symmetric_filter<closable_symmetric_filter>
- (0, seq.new_operation(2))
- );
- ch.push(closable_device<input>(seq.new_operation(1)));
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Test output
- {
- operation_sequence seq;
- chain<output> ch;
- ch.push(
- io::symmetric_filter<closable_symmetric_filter>
- (0, seq.new_operation(1))
- );
- ch.push(closable_device<output>(seq.new_operation(2)));
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-}
-
-void tee_test()
-{
- // Note: The implementation of tee_device closes the first
- // sink before the second
-
- // Tee two sinks (Borland <= 5.8.2 needs a little help compiling this case,
- // but it executes the closing algorithm correctly)
- {
- operation_sequence seq;
- chain<output> ch;
- ch.push(
- io::tee(
- closable_device<output>(seq.new_operation(1)),
- closable_device<
- #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
- borland_output
- #else
- output
- #endif
- >(seq.new_operation(2))
- )
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Tee two bidirectional devices
- {
- operation_sequence seq;
- chain<output> ch;
- ch.push(
- io::tee(
- closable_device<bidirectional>(
- seq.new_operation(1),
- seq.new_operation(2)
- ),
- closable_device<bidirectional>(
- seq.new_operation(3),
- seq.new_operation(4)
- )
- )
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Tee two seekable devices
- {
- operation_sequence seq;
- chain<output> ch;
- ch.push(
- io::tee(
- closable_device<seekable>(seq.new_operation(1)),
- closable_device<seekable>(seq.new_operation(2))
- )
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Tee a sink
- {
- operation_sequence seq;
- chain<output> ch;
- ch.push(io::tee(closable_device<output>(seq.new_operation(1))));
- ch.push(closable_device<output>(seq.new_operation(2)));
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Tee a bidirectional device
- {
- operation_sequence seq;
- chain<output> ch;
- ch.push(
- io::tee(
- closable_device<bidirectional>(
- seq.new_operation(1),
- seq.new_operation(2)
- )
- )
- );
- ch.push(closable_device<output>(seq.new_operation(3)));
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Tee a seekable device
- {
- operation_sequence seq;
- chain<output> ch;
- ch.push(io::tee(closable_device<seekable>(seq.new_operation(1))));
- ch.push(closable_device<seekable>(seq.new_operation(2)));
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-}
-
-void tee_composite_test()
-{
- // This test is probably redundant, but it verifies that
- // ticket #1002 is fixed
-
- // Tee a composite sink with a sink
- {
- operation_sequence seq;
- chain<output> ch;
- ch.push(
- io::tee(
- io::compose(
- closable_filter<output>(seq.new_operation(1)),
- closable_device<output>(seq.new_operation(2))
- ),
- closable_device<output>(seq.new_operation(3))
- )
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Tee a composite bidirectional device with a sink
- {
- operation_sequence seq;
- chain<output> ch;
- ch.push(
- io::tee(
- io::compose(
- closable_filter<bidirectional>(
- seq.new_operation(2),
- seq.new_operation(3)
- ),
- closable_device<bidirectional>(
- seq.new_operation(1),
- seq.new_operation(4)
- )
- ),
- closable_device<output>(seq.new_operation(5))
- )
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Tee a composite composite seekable device with a sink
- {
- operation_sequence seq;
- chain<output> ch;
- ch.push(
- io::tee(
- io::compose(
- closable_filter<seekable>(seq.new_operation(1)),
- closable_device<seekable>(seq.new_operation(2))
- ),
- closable_device<output>(seq.new_operation(3))
- )
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
-
- // Tee a composite sink
- {
- operation_sequence seq;
- chain<output> ch;
- ch.push(
- io::tee(
- io::compose(
- closable_filter<output>(seq.new_operation(1)),
- closable_device<output>(seq.new_operation(2))
- )
- )
- );
- ch.push(closable_device<output>(seq.new_operation(3)));
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Tee a composite bidirectional device with a sink
- {
- operation_sequence seq;
- chain<output> ch;
- ch.push(
- io::tee(
- io::compose(
- closable_filter<bidirectional>(
- seq.new_operation(2),
- seq.new_operation(3)
- ),
- closable_device<bidirectional>(
- seq.new_operation(1),
- seq.new_operation(4)
- )
- )
- )
- );
- ch.push(closable_device<output>(seq.new_operation(5)));
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
- // Tee a composite composite seekable device with a sink
- {
- operation_sequence seq;
- chain<output> ch;
- ch.push(
- io::tee(
- io::compose(
- closable_filter<seekable>(seq.new_operation(1)),
- closable_device<seekable>(seq.new_operation(2))
- )
- )
- );
- ch.push(closable_device<output>(seq.new_operation(3)));
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-}
-
 test_suite* init_unit_test_suite(int, char* [])
 {
     test_suite* test = BOOST_TEST_SUITE("execute test");
@@ -1413,13 +514,5 @@
     test->add(BOOST_TEST_CASE(&bidirectional_chain_test));
     test->add(BOOST_TEST_CASE(&seekable_chain_test));
     test->add(BOOST_TEST_CASE(&stream_test));
- test->add(BOOST_TEST_CASE(&combine_test));
- test->add(BOOST_TEST_CASE(&composite_device_test));
- test->add(BOOST_TEST_CASE(&composite_filter_test));
- test->add(BOOST_TEST_CASE(&invert_test));
- test->add(BOOST_TEST_CASE(&restrict_test));
- test->add(BOOST_TEST_CASE(&symmetric_filter_test));
- test->add(BOOST_TEST_CASE(&tee_test));
- test->add(BOOST_TEST_CASE(&tee_composite_test));
     return test;
 }

Modified: trunk/libs/iostreams/test/compose_test.cpp
==============================================================================
--- trunk/libs/iostreams/test/compose_test.cpp (original)
+++ trunk/libs/iostreams/test/compose_test.cpp 2008-01-06 13:32:05 EST (Sun, 06 Jan 2008)
@@ -10,6 +10,8 @@
 #include <boost/iostreams/filtering_stream.hpp>
 #include <boost/test/test_tools.hpp>
 #include <boost/test/unit_test.hpp>
+#include "detail/closable.hpp"
+#include "detail/operation_sequence.hpp"
 #include "detail/filters.hpp"
 #include "detail/temp_file.hpp"
 #include "detail/verification.hpp"
@@ -17,13 +19,14 @@
 // Must come last.
 #include <boost/iostreams/detail/config/disable_warnings.hpp> // BCC 5.x.
 
+using namespace std;
 using namespace boost::iostreams;
+using namespace boost::iostreams::test;
 using boost::unit_test::test_suite;
+namespace io = boost::iostreams;
 
 void read_composite()
 {
- using namespace boost::iostreams::test;
-
     test_file src1, src2;
     filtering_istream first, second;
 
@@ -56,9 +59,6 @@
 
 void write_composite()
 {
- using namespace std;
- using namespace boost::iostreams::test;
-
     temp_file dest1, dest2;
     filtering_ostream out1, out2;
 
@@ -105,11 +105,392 @@
     }
 }
 
+void close_composite_device()
+{
+ // Compose an input filter with a source
+ {
+ operation_sequence seq;
+ chain<input> ch;
+ ch.push(
+ io::compose(
+ closable_filter<input>(seq.new_operation(2)),
+ closable_device<input>(seq.new_operation(1))
+ )
+ );
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Compose a bidirectional filter with a source
+ {
+ operation_sequence seq;
+ chain<input> ch;
+ ch.push(
+ io::compose(
+ closable_filter<bidirectional>(
+ seq.new_operation(2),
+ seq.new_operation(3)
+ ),
+ closable_device<input>(seq.new_operation(1))
+ )
+ );
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Compose a seekable filter with a source
+ {
+ operation_sequence seq;
+ chain<input> ch;
+ ch.push(
+ io::compose(
+ closable_filter<seekable>(seq.new_operation(2)),
+ closable_device<input>(seq.new_operation(1))
+ )
+ );
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Compose a dual-use filter with a source
+ {
+ operation_sequence seq;
+ chain<input> ch;
+ ch.push(
+ io::compose(
+ closable_filter<dual_use>(
+ seq.new_operation(2),
+ seq.new_operation(3)
+ ),
+ closable_device<input>(seq.new_operation(1))
+ )
+ );
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Compose an output filter with a sink
+ {
+ operation_sequence seq;
+ chain<output> ch;
+ ch.push(
+ io::compose(
+ closable_filter<output>(seq.new_operation(1)),
+ closable_device<output>(seq.new_operation(2))
+ )
+ );
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Compose a bidirectional filter with a sink
+ {
+ operation_sequence seq;
+ chain<output> ch;
+ ch.push(
+ io::compose(
+ closable_filter<bidirectional>(
+ seq.new_operation(1),
+ seq.new_operation(2)
+ ),
+ closable_device<output>(seq.new_operation(3))
+ )
+ );
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Compose a seekable filter with a sink
+ {
+ operation_sequence seq;
+ chain<output> ch;
+ ch.push(
+ io::compose(
+ closable_filter<seekable>(seq.new_operation(1)),
+ closable_device<output>(seq.new_operation(2))
+ )
+ );
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Compose a dual-use filter with a sink
+ {
+ operation_sequence seq;
+ chain<output> ch;
+ ch.push(
+ io::compose(
+ closable_filter<dual_use>(
+ seq.new_operation(1),
+ seq.new_operation(2)
+ ),
+ closable_device<output>(seq.new_operation(3))
+ )
+ );
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Compose a bidirectional filter with a bidirectional device
+ {
+ operation_sequence seq;
+ chain<bidirectional> ch;
+ ch.push(
+ io::compose(
+ closable_filter<bidirectional>(
+ seq.new_operation(2),
+ seq.new_operation(3)
+ ),
+ closable_device<bidirectional>(
+ seq.new_operation(1),
+ seq.new_operation(4)
+ )
+ )
+ );
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Compose a seekable filter with a seekable device
+ {
+ operation_sequence seq;
+ chain<seekable> ch;
+ ch.push(
+ io::compose(
+ closable_filter<seekable>(seq.new_operation(1)),
+ closable_device<seekable>(seq.new_operation(2))
+ )
+ );
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+}
+
+void close_composite_filter()
+{
+ // Compose two input filters
+ {
+ operation_sequence seq;
+ chain<input> ch;
+ ch.push(
+ io::compose(
+ closable_filter<input>(seq.new_operation(3)),
+ closable_filter<input>(seq.new_operation(2))
+ )
+ );
+ ch.push(closable_device<input>(seq.new_operation(1)));
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Compose a bidirectional filter with an input filter
+ {
+ operation_sequence seq;
+ chain<input> ch;
+ ch.push(
+ io::compose(
+ closable_filter<bidirectional>(
+ seq.new_operation(3),
+ seq.new_operation(4)
+ ),
+ closable_filter<input>(seq.new_operation(2))
+ )
+ );
+ ch.push(closable_device<input>(seq.new_operation(1)));
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_MESSAGE(seq.is_success(), seq.message());
+ }
+
+ // Compose a seekable filter with an input filter
+ {
+ operation_sequence seq;
+ chain<input> ch;
+ ch.push(
+ io::compose(
+ closable_filter<seekable>(seq.new_operation(3)),
+ closable_filter<input>(seq.new_operation(2))
+ )
+ );
+ ch.push(closable_device<input>(seq.new_operation(1)));
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Compose a dual-use filter with an input filter
+ {
+ operation_sequence seq;
+ chain<input> ch;
+ ch.push(
+ io::compose(
+ closable_filter<dual_use>(
+ seq.new_operation(3),
+ seq.new_operation(4)
+ ),
+ closable_filter<input>(seq.new_operation(2))
+ )
+ );
+ ch.push(closable_device<input>(seq.new_operation(1)));
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Compose two output filters
+ {
+ operation_sequence seq;
+ chain<output> ch;
+ ch.push(
+ io::compose(
+ closable_filter<output>(seq.new_operation(1)),
+ closable_filter<output>(seq.new_operation(2))
+ )
+ );
+ ch.push(closable_device<output>(seq.new_operation(3)));
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Compose a bidirectional filter with an output filter
+ {
+ operation_sequence seq;
+ chain<output> ch;
+ ch.push(
+ io::compose(
+ closable_filter<bidirectional>(
+ seq.new_operation(1),
+ seq.new_operation(2)
+ ),
+ closable_filter<output>(seq.new_operation(3))
+ )
+ );
+ ch.push(closable_device<output>(seq.new_operation(4)));
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Compose a seekable filter with an output filter
+ {
+ operation_sequence seq;
+ chain<output> ch;
+ ch.push(
+ io::compose(
+ closable_filter<seekable>(seq.new_operation(1)),
+ closable_filter<output>(seq.new_operation(2))
+ )
+ );
+ ch.push(closable_device<output>(seq.new_operation(3)));
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Compose a dual-use filter with an output filter
+ {
+ operation_sequence seq;
+ chain<output> ch;
+ ch.push(
+ io::compose(
+ closable_filter<dual_use>(
+ seq.new_operation(1),
+ seq.new_operation(2)
+ ),
+ closable_filter<output>(seq.new_operation(3))
+ )
+ );
+ ch.push(closable_device<output>(seq.new_operation(4)));
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Compose two bidirectional filters
+ {
+ operation_sequence seq;
+ chain<bidirectional> ch;
+ ch.push(
+ io::compose(
+ closable_filter<bidirectional>(
+ seq.new_operation(3),
+ seq.new_operation(4)
+ ),
+ closable_filter<bidirectional>(
+ seq.new_operation(2),
+ seq.new_operation(5)
+ )
+ )
+ );
+ ch.push(
+ closable_device<bidirectional>(
+ seq.new_operation(1),
+ seq.new_operation(6)
+ )
+ );
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Compose two seekable filters
+ {
+ operation_sequence seq;
+ chain<seekable> ch;
+ ch.push(
+ io::compose(
+ closable_filter<seekable>(seq.new_operation(1)),
+ closable_filter<seekable>(seq.new_operation(2))
+ )
+ );
+ ch.push(closable_device<seekable>(seq.new_operation(3)));
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Compose two dual-use filters for input
+ {
+ operation_sequence seq;
+ chain<input> ch;
+ ch.push(
+ io::compose(
+ closable_filter<dual_use>(
+ seq.new_operation(3),
+ seq.new_operation(4)
+ ),
+ closable_filter<dual_use>(
+ seq.new_operation(2),
+ seq.new_operation(5)
+ )
+ )
+ );
+ ch.push(closable_device<input>(seq.new_operation(1)));
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Compose two dual-use filters for output
+ {
+ operation_sequence seq;
+ chain<output> ch;
+ ch.push(
+ io::compose(
+ closable_filter<dual_use>(
+ seq.new_operation(2),
+ seq.new_operation(3)
+ ),
+ closable_filter<dual_use>(
+ seq.new_operation(1),
+ seq.new_operation(4)
+ )
+ )
+ );
+ ch.push(closable_device<output>(seq.new_operation(5)));
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+}
+
 test_suite* init_unit_test_suite(int, char* [])
 {
     test_suite* test = BOOST_TEST_SUITE("line_filter test");
     test->add(BOOST_TEST_CASE(&read_composite));
     test->add(BOOST_TEST_CASE(&write_composite));
+ test->add(BOOST_TEST_CASE(&close_composite_device));
+ test->add(BOOST_TEST_CASE(&close_composite_filter));
     return test;
 }
 

Modified: trunk/libs/iostreams/test/invert_test.cpp
==============================================================================
--- trunk/libs/iostreams/test/invert_test.cpp (original)
+++ trunk/libs/iostreams/test/invert_test.cpp 2008-01-06 13:32:05 EST (Sun, 06 Jan 2008)
@@ -9,14 +9,17 @@
 #include <boost/iostreams/invert.hpp>
 #include <boost/test/test_tools.hpp>
 #include <boost/test/unit_test.hpp>
+#include "detail/closable.hpp"
 #include "detail/filters.hpp"
+#include "detail/operation_sequence.hpp"
 #include "detail/temp_file.hpp"
 
 using namespace boost::iostreams;
 using namespace boost::iostreams::test;
-using boost::unit_test::test_suite;
+using boost::unit_test::test_suite;
+namespace io = boost::iostreams;
 
-void inverse_test()
+void read_write_test()
 {
 
     test_file test;
@@ -34,10 +37,33 @@
                     file_source(upper.name(), in_mode) ) );
 }
 
+void close_test()
+{
+ // Invert an output filter
+ {
+ operation_sequence seq;
+ chain<input> ch;
+ ch.push(io::invert(closable_filter<output>(seq.new_operation(2))));
+ ch.push(closable_device<input>(seq.new_operation(1)));
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Invert an input filter
+ {
+ operation_sequence seq;
+ chain<output> ch;
+ ch.push(io::invert(closable_filter<input>(seq.new_operation(1))));
+ ch.push(closable_device<output>(seq.new_operation(2)));
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+}
 
 test_suite* init_unit_test_suite(int, char* [])
 {
     test_suite* test = BOOST_TEST_SUITE("reverse test");
- test->add(BOOST_TEST_CASE(&inverse_test));
+ test->add(BOOST_TEST_CASE(&read_write_test));
+ test->add(BOOST_TEST_CASE(&close_test));
     return test;
 }

Modified: trunk/libs/iostreams/test/restrict_test.cpp
==============================================================================
--- trunk/libs/iostreams/test/restrict_test.cpp (original)
+++ trunk/libs/iostreams/test/restrict_test.cpp 2008-01-06 13:32:05 EST (Sun, 06 Jan 2008)
@@ -17,17 +17,19 @@
 #include <boost/iostreams/restrict.hpp>
 #include <boost/test/test_tools.hpp>
 #include <boost/test/unit_test.hpp>
+#include "detail/closable.hpp"
 #include "detail/constants.hpp"
 #include "detail/filters.hpp"
+#include "detail/operation_sequence.hpp"
 #include "detail/sequence.hpp"
 #include "detail/temp_file.hpp"
 #include "detail/verification.hpp"
 
 using namespace std;
-using namespace boost;
 using namespace boost::iostreams;
 using namespace boost::iostreams::test;
-using boost::unit_test::test_suite;
+using boost::unit_test::test_suite;
+namespace io = boost::iostreams;
 
 const char pad_char = '\n';
 const int small_padding = 50;
@@ -521,6 +523,115 @@
     }
 }
 
+void close_device()
+{
+ // Restrict a source
+ {
+ operation_sequence seq;
+ chain<input> ch;
+ ch.push(io::restrict(closable_device<input>(seq.new_operation(1)), 0));
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Restrict a seekable device
+ {
+ operation_sequence seq;
+ chain<seekable> ch;
+ ch.push(
+ io::restrict(closable_device<seekable>(seq.new_operation(1)), 0)
+ );
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Restrict a direct source
+ {
+ operation_sequence seq;
+ chain<input> ch;
+ ch.push(
+ io::restrict(closable_device<direct_input>(seq.new_operation(1)), 0)
+ );
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Restrict a direct seekable device
+ {
+ operation_sequence seq;
+ chain<seekable> ch;
+ ch.push(
+ io::restrict(
+ closable_device<direct_seekable>(seq.new_operation(1)),
+ 0
+ )
+ );
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+}
+
+void close_filter()
+{
+ // Restrict an input filter
+ {
+ operation_sequence seq;
+ chain<input> ch;
+ ch.push(io::restrict(closable_filter<input>(seq.new_operation(2)), 0));
+ ch.push(closable_device<input>(seq.new_operation(1)));
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Restrict a seekable filter
+ {
+ operation_sequence seq;
+ chain<seekable> ch;
+ ch.push(
+ io::restrict(closable_filter<seekable>(seq.new_operation(1)), 0)
+ );
+ ch.push(closable_device<seekable>(seq.new_operation(2)));
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Restrict a dual_use filter for input
+ {
+ operation_sequence seq;
+ chain<input> ch;
+ ch.push(
+ io::restrict(
+ closable_filter<dual_use>(
+ seq.new_operation(2),
+ seq.new_operation(3)
+ ),
+ 0
+ )
+ );
+ ch.push(closable_device<input>(seq.new_operation(1)));
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Restrict a dual_use filter for output
+ {
+ operation_sequence seq;
+ chain<output> ch;
+ ch.push(
+ io::restrict(
+ closable_filter<dual_use>(
+ seq.new_operation(1),
+ seq.new_operation(2)
+ ),
+ 0
+ )
+ );
+ ch.push(closable_device<output>(seq.new_operation(3)));
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+}
+
 test_suite* init_unit_test_suite(int, char* [])
 {
     test_suite* test = BOOST_TEST_SUITE("restrict test");
@@ -532,5 +643,7 @@
     test->add(BOOST_TEST_CASE(&write_filter));
     test->add(BOOST_TEST_CASE(&seek_device));
     test->add(BOOST_TEST_CASE(&seek_direct_device));
+ test->add(BOOST_TEST_CASE(&close_device));
+ test->add(BOOST_TEST_CASE(&close_filter));
     return test;
 }

Modified: trunk/libs/iostreams/test/symmetric_filter_test.cpp
==============================================================================
--- trunk/libs/iostreams/test/symmetric_filter_test.cpp (original)
+++ trunk/libs/iostreams/test/symmetric_filter_test.cpp 2008-01-06 13:32:05 EST (Sun, 06 Jan 2008)
@@ -10,7 +10,9 @@
 #include <boost/iostreams/filter/test.hpp>
 #include <boost/test/test_tools.hpp>
 #include <boost/test/unit_test.hpp>
+#include "detail/closable.hpp"
 #include "./detail/constants.hpp"
+#include "detail/operation_sequence.hpp"
 #include "./detail/temp_file.hpp"
 #include "./detail/verification.hpp"
 
@@ -19,7 +21,8 @@
 
 using namespace boost::iostreams;
 using namespace boost::iostreams::test;
-using boost::unit_test::test_suite;
+using boost::unit_test::test_suite;
+namespace io = boost::iostreams;
 
 // Note: The filter is given an internal buffer -- unnecessary in this simple
 // case -- to stress test symmetric_filter.
@@ -77,7 +80,7 @@
 typedef symmetric_filter<toupper_symmetric_filter_impl>
         toupper_symmetric_filter;
 
-void read_symmetric_filter_test()
+void read_symmetric_filter()
 {
     test_file test;
     uppercase_file upper;
@@ -88,7 +91,7 @@
     );
 }
 
-void write_symmetric_filter_test()
+void write_symmetric_filter()
 {
     test_file test;
     uppercase_file upper;
@@ -99,11 +102,41 @@
     );
 }
 
+void close_symmetric_filter()
+{
+ // Test input
+ {
+ operation_sequence seq;
+ chain<input> ch;
+ ch.push(
+ io::symmetric_filter<closable_symmetric_filter>
+ (0, seq.new_operation(2))
+ );
+ ch.push(closable_device<input>(seq.new_operation(1)));
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Test output
+ {
+ operation_sequence seq;
+ chain<output> ch;
+ ch.push(
+ io::symmetric_filter<closable_symmetric_filter>
+ (0, seq.new_operation(1))
+ );
+ ch.push(closable_device<output>(seq.new_operation(2)));
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+}
+
 test_suite* init_unit_test_suite(int, char* [])
 {
     test_suite* test = BOOST_TEST_SUITE("symmetric_filter test");
- test->add(BOOST_TEST_CASE(&read_symmetric_filter_test));
- test->add(BOOST_TEST_CASE(&write_symmetric_filter_test));
+ test->add(BOOST_TEST_CASE(&read_symmetric_filter));
+ test->add(BOOST_TEST_CASE(&write_symmetric_filter));
+ test->add(BOOST_TEST_CASE(&close_symmetric_filter));
     return test;
 }
 

Modified: trunk/libs/iostreams/test/tee_test.cpp
==============================================================================
--- trunk/libs/iostreams/test/tee_test.cpp (original)
+++ trunk/libs/iostreams/test/tee_test.cpp 2008-01-06 13:32:05 EST (Sun, 06 Jan 2008)
@@ -5,11 +5,14 @@
 // See http://www.boost.org/libs/iostreams for documentation.
 
 #include <fstream>
+#include <boost/iostreams/compose.hpp>
 #include <boost/iostreams/device/file.hpp>
 #include <boost/iostreams/filtering_stream.hpp>
 #include <boost/iostreams/tee.hpp>
 #include <boost/test/test_tools.hpp>
 #include <boost/test/unit_test.hpp>
+#include "detail/closable.hpp"
+#include "detail/operation_sequence.hpp"
 #include "detail/temp_file.hpp"
 #include "detail/verification.hpp"
 
@@ -18,8 +21,9 @@
 using namespace boost::iostreams;
 using namespace boost::iostreams::test;
 using boost::unit_test::test_suite;
+namespace io = boost::iostreams;
 
-void tee_test()
+void read_write_test()
 {
     {
         temp_file dest1;
@@ -78,9 +82,229 @@
     }
 }
 
+void close_test()
+{
+ // Note: The implementation of tee_device closes the first
+ // sink before the second
+
+ // Tee two sinks (Borland <= 5.8.2 needs a little help compiling this case,
+ // but it executes the closing algorithm correctly)
+ {
+ operation_sequence seq;
+ chain<output> ch;
+ ch.push(
+ io::tee(
+ closable_device<output>(seq.new_operation(1)),
+ closable_device<
+ #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
+ borland_output
+ #else
+ output
+ #endif
+ >(seq.new_operation(2))
+ )
+ );
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Tee two bidirectional devices
+ {
+ operation_sequence seq;
+ chain<output> ch;
+ ch.push(
+ io::tee(
+ closable_device<bidirectional>(
+ seq.new_operation(1),
+ seq.new_operation(2)
+ ),
+ closable_device<bidirectional>(
+ seq.new_operation(3),
+ seq.new_operation(4)
+ )
+ )
+ );
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Tee two seekable devices
+ {
+ operation_sequence seq;
+ chain<output> ch;
+ ch.push(
+ io::tee(
+ closable_device<seekable>(seq.new_operation(1)),
+ closable_device<seekable>(seq.new_operation(2))
+ )
+ );
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Tee a sink
+ {
+ operation_sequence seq;
+ chain<output> ch;
+ ch.push(io::tee(closable_device<output>(seq.new_operation(1))));
+ ch.push(closable_device<output>(seq.new_operation(2)));
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Tee a bidirectional device
+ {
+ operation_sequence seq;
+ chain<output> ch;
+ ch.push(
+ io::tee(
+ closable_device<bidirectional>(
+ seq.new_operation(1),
+ seq.new_operation(2)
+ )
+ )
+ );
+ ch.push(closable_device<output>(seq.new_operation(3)));
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Tee a seekable device
+ {
+ operation_sequence seq;
+ chain<output> ch;
+ ch.push(io::tee(closable_device<seekable>(seq.new_operation(1))));
+ ch.push(closable_device<seekable>(seq.new_operation(2)));
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+}
+
+void tee_composite_test()
+{
+ // This test is probably redundant, given the above test and the tests in
+ // compose_test.cpp, but it verifies that ticket #1002 is fixed
+
+ // Tee a composite sink with a sink
+ {
+ operation_sequence seq;
+ chain<output> ch;
+ ch.push(
+ io::tee(
+ io::compose(
+ closable_filter<output>(seq.new_operation(1)),
+ closable_device<output>(seq.new_operation(2))
+ ),
+ closable_device<output>(seq.new_operation(3))
+ )
+ );
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Tee a composite bidirectional device with a sink
+ {
+ operation_sequence seq;
+ chain<output> ch;
+ ch.push(
+ io::tee(
+ io::compose(
+ closable_filter<bidirectional>(
+ seq.new_operation(2),
+ seq.new_operation(3)
+ ),
+ closable_device<bidirectional>(
+ seq.new_operation(1),
+ seq.new_operation(4)
+ )
+ ),
+ closable_device<output>(seq.new_operation(5))
+ )
+ );
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Tee a composite composite seekable device with a sink
+ {
+ operation_sequence seq;
+ chain<output> ch;
+ ch.push(
+ io::tee(
+ io::compose(
+ closable_filter<seekable>(seq.new_operation(1)),
+ closable_device<seekable>(seq.new_operation(2))
+ ),
+ closable_device<output>(seq.new_operation(3))
+ )
+ );
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+
+ // Tee a composite sink
+ {
+ operation_sequence seq;
+ chain<output> ch;
+ ch.push(
+ io::tee(
+ io::compose(
+ closable_filter<output>(seq.new_operation(1)),
+ closable_device<output>(seq.new_operation(2))
+ )
+ )
+ );
+ ch.push(closable_device<output>(seq.new_operation(3)));
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Tee a composite bidirectional device with a sink
+ {
+ operation_sequence seq;
+ chain<output> ch;
+ ch.push(
+ io::tee(
+ io::compose(
+ closable_filter<bidirectional>(
+ seq.new_operation(2),
+ seq.new_operation(3)
+ ),
+ closable_device<bidirectional>(
+ seq.new_operation(1),
+ seq.new_operation(4)
+ )
+ )
+ )
+ );
+ ch.push(closable_device<output>(seq.new_operation(5)));
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+
+ // Tee a composite composite seekable device with a sink
+ {
+ operation_sequence seq;
+ chain<output> ch;
+ ch.push(
+ io::tee(
+ io::compose(
+ closable_filter<seekable>(seq.new_operation(1)),
+ closable_device<seekable>(seq.new_operation(2))
+ )
+ )
+ );
+ ch.push(closable_device<output>(seq.new_operation(3)));
+ BOOST_CHECK_NO_THROW(ch.reset());
+ BOOST_CHECK_OPERATION_SEQUENCE(seq);
+ }
+}
+
 test_suite* init_unit_test_suite(int, char* [])
 {
     test_suite* test = BOOST_TEST_SUITE("tee test");
- test->add(BOOST_TEST_CASE(&tee_test));
+ test->add(BOOST_TEST_CASE(&read_write_test));
+ test->add(BOOST_TEST_CASE(&close_test));
     return test;
 }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk