$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: technews_at_[hidden]
Date: 2008-01-13 02:33:40
Author: turkanis
Date: 2008-01-13 02:33:37 EST (Sun, 13 Jan 2008)
New Revision: 42714
URL: http://svn.boost.org/trac/boost/changeset/42714
Log:
full merge from trunk at 42712 of boost/iostreams and libs/iostreams
Added:
   branches/release/boost/iostreams/detail/config/fpos.hpp
      - copied unchanged from r42713, /trunk/boost/iostreams/detail/config/fpos.hpp
   branches/release/boost/iostreams/detail/restrict_impl.hpp
      - copied unchanged from r42713, /trunk/boost/iostreams/detail/restrict_impl.hpp
   branches/release/boost/iostreams/slice.hpp
      - copied unchanged from r42713, /trunk/boost/iostreams/slice.hpp
   branches/release/libs/iostreams/test/combine_test.cpp
      - copied unchanged from r42713, /trunk/libs/iostreams/test/combine_test.cpp
   branches/release/libs/iostreams/test/slice_test.cpp
      - copied unchanged from r42713, /trunk/libs/iostreams/test/slice_test.cpp
Text files modified: 
   branches/release/boost/iostreams/copy.hpp                                |     7                                         
   branches/release/boost/iostreams/detail/config/codecvt.hpp               |     3                                         
   branches/release/boost/iostreams/detail/config/rtl.hpp                   |    24                                         
   branches/release/boost/iostreams/detail/streambuf/direct_streambuf.hpp   |     5                                         
   branches/release/boost/iostreams/detail/streambuf/indirect_streambuf.hpp |     7                                         
   branches/release/boost/iostreams/device/file_descriptor.hpp              |    73 +-                                      
   branches/release/boost/iostreams/filter/aggregate.hpp                    |     3                                         
   branches/release/boost/iostreams/filter/gzip.hpp                         |     2                                         
   branches/release/boost/iostreams/filter/line.hpp                         |     2                                         
   branches/release/boost/iostreams/filter/newline.hpp                      |     6                                         
   branches/release/boost/iostreams/input_sequence.hpp                      |     1                                         
   branches/release/boost/iostreams/output_sequence.hpp                     |     1                                         
   branches/release/boost/iostreams/positioning.hpp                         |    96 ++-                                     
   branches/release/boost/iostreams/restrict.hpp                            |   455 -------------------                     
   branches/release/libs/iostreams/src/file_descriptor.cpp                  |   131 +++--                                   
   branches/release/libs/iostreams/test/Jamfile.v2                          |    27                                         
   branches/release/libs/iostreams/test/close_test.cpp                      |   915 --------------------------------------- 
   branches/release/libs/iostreams/test/compose_test.cpp                    |   391 ++++++++++++++++                        
   branches/release/libs/iostreams/test/invert_test.cpp                     |    32 +                                       
   branches/release/libs/iostreams/test/large_file_test.cpp                 |     6                                         
   branches/release/libs/iostreams/test/operation_sequence_test.cpp         |     5                                         
   branches/release/libs/iostreams/test/restrict_test.cpp                   |   234 ++++++++-                               
   branches/release/libs/iostreams/test/stream_offset_64bit_test.cpp        |    16                                         
   branches/release/libs/iostreams/test/symmetric_filter_test.cpp           |    43 +                                       
   branches/release/libs/iostreams/test/tee_test.cpp                        |   228 +++++++++                               
   25 files changed, 1126 insertions(+), 1587 deletions(-)
Modified: branches/release/boost/iostreams/copy.hpp
==============================================================================
--- branches/release/boost/iostreams/copy.hpp	(original)
+++ branches/release/boost/iostreams/copy.hpp	2008-01-13 02:33:37 EST (Sun, 13 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: branches/release/boost/iostreams/detail/config/codecvt.hpp
==============================================================================
--- branches/release/boost/iostreams/detail/config/codecvt.hpp	(original)
+++ branches/release/boost/iostreams/detail/config/codecvt.hpp	2008-01-13 02:33:37 EST (Sun, 13 Jan 2008)
@@ -41,7 +41,8 @@
 //------------------Normalize codecvt::length---------------------------------//
 
 #if !defined(__MSL_CPP__) && !defined(__LIBCOMO__) && \
-    (!defined(BOOST_RWSTD_VER) || BOOST_RWSTD_VER < 0x04010300)
+    (!defined(BOOST_RWSTD_VER) || BOOST_RWSTD_VER < 0x04010300) && \
+    (!defined(__MACH__) || !defined(__INTEL_COMPILER))
     /**/
 # define BOOST_IOSTREAMS_CODECVT_CV_QUALIFIER const
 #else
Modified: branches/release/boost/iostreams/detail/config/rtl.hpp
==============================================================================
--- branches/release/boost/iostreams/detail/config/rtl.hpp	(original)
+++ branches/release/boost/iostreams/detail/config/rtl.hpp	2008-01-13 02:33:37 EST (Sun, 13 Jan 2008)
@@ -22,22 +22,20 @@
 #include <boost/iostreams/detail/config/windows_posix.hpp>
 
 // Handle open, close, read, and write
-#if defined(__BORLANDC__)
+#ifdef __BORLANDC__
 # define BOOST_IOSTREAMS_RTL(x) BOOST_JOIN(_rtl_, x)
+#elif defined BOOST_IOSTREAMS_WINDOWS
+# define BOOST_IOSTREAMS_RTL(x) BOOST_JOIN(_, x)
 #else
-# if defined(BOOST_IOSTREAMS_WINDOWS) && !defined(__CYGWIN__)
-#  define BOOST_IOSTREAMS_RTL(x) BOOST_JOIN(_, x)
-# else
-#  define BOOST_IOSTREAMS_RTL(x) ::x
-# endif
+# define BOOST_IOSTREAMS_RTL(x) ::x  // Distinguish from member function named x
 #endif
 #define BOOST_IOSTREAMS_FD_OPEN   BOOST_IOSTREAMS_RTL(open)
 #define BOOST_IOSTREAMS_FD_CLOSE  BOOST_IOSTREAMS_RTL(close)
 #define BOOST_IOSTREAMS_FD_READ   BOOST_IOSTREAMS_RTL(read)
 #define BOOST_IOSTREAMS_FD_WRITE  BOOST_IOSTREAMS_RTL(write)
 
-// Handle lseek, ftruncate, stat, and off_t
-#if defined(BOOST_IOSTREAMS_WINDOWS) && !defined(__CYGWIN__)
+// Handle lseek, off_t, ftruncate, and stat
+#ifdef BOOST_IOSTREAMS_WINDOWS
 # if defined(BOOST_MSVC) || defined(__MSVCRT__) // MSVC, MinGW
 #  define BOOST_IOSTREAMS_FD_SEEK    _lseeki64
 #  define BOOST_IOSTREAMS_FD_OFFSET  __int64
@@ -48,13 +46,17 @@
 #else // Non-windows
 # if defined(_LARGEFILE64_SOURCE) && \
          (!defined(_FILE_OFFSET_BITS) || _FILE_OFFSET_BITS != 64) || \
-     defined(BOOST_IOSTREAMS_HAS_LSEEK64) \
+     defined(__IBMCPP__) && !defined(_LARGE_FILES) || \
+     defined(BOOST_IOSTREAMS_HAS_LARGE_FILE_EXTENSIONS)
      /**/
-#  define BOOST_IOSTREAMS_FD_SEEK      lseek64  // GCC for some 32-bit *nix
+
+    /* Systems with transitional extensions for large file support */
+
+#  define BOOST_IOSTREAMS_FD_SEEK      lseek64
 #  define BOOST_IOSTREAMS_FD_TRUNCATE  ftruncate64
 #  define BOOST_IOSTREAMS_FD_STAT      stat64
 #  define BOOST_IOSTREAMS_FD_OFFSET    off64_t
-# else                                          // Cygwin, Darwin, ...
+# else
 #  define BOOST_IOSTREAMS_FD_SEEK      lseek
 #  define BOOST_IOSTREAMS_FD_TRUNCATE  ftruncate
 #  define BOOST_IOSTREAMS_FD_STAT      stat
Modified: branches/release/boost/iostreams/detail/streambuf/direct_streambuf.hpp
==============================================================================
--- branches/release/boost/iostreams/detail/streambuf/direct_streambuf.hpp	(original)
+++ branches/release/boost/iostreams/detail/streambuf/direct_streambuf.hpp	2008-01-13 02:33:37 EST (Sun, 13 Jan 2008)
@@ -187,10 +187,9 @@
 template<typename T, typename Tr>
 inline typename direct_streambuf<T, Tr>::pos_type
 direct_streambuf<T, Tr>::seekpos
-    (pos_type sp, BOOST_IOS::openmode)
+    (pos_type sp, BOOST_IOS::openmode which)
 { 
-    return seek_impl( position_to_offset(sp), BOOST_IOS::beg, 
-                      BOOST_IOS::in | BOOST_IOS::out );
+    return seek_impl(position_to_offset(sp), BOOST_IOS::beg, which);
 }
 
 template<typename T, typename Tr>
Modified: branches/release/boost/iostreams/detail/streambuf/indirect_streambuf.hpp
==============================================================================
--- branches/release/boost/iostreams/detail/streambuf/indirect_streambuf.hpp	(original)
+++ branches/release/boost/iostreams/detail/streambuf/indirect_streambuf.hpp	2008-01-13 02:33:37 EST (Sun, 13 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_;
@@ -332,10 +332,9 @@
 template<typename T, typename Tr, typename Alloc, typename Mode>
 inline typename indirect_streambuf<T, Tr, Alloc, Mode>::pos_type
 indirect_streambuf<T, Tr, Alloc, Mode>::seekpos
-    (pos_type sp, BOOST_IOS::openmode)
+    (pos_type sp, BOOST_IOS::openmode which)
 { 
-    return seek_impl( position_to_offset(sp), BOOST_IOS::beg, 
-                      BOOST_IOS::in | BOOST_IOS::out ); 
+    return seek_impl(position_to_offset(sp), BOOST_IOS::beg, which); 
 }
 
 template<typename T, typename Tr, typename Alloc, typename Mode>
Modified: branches/release/boost/iostreams/device/file_descriptor.hpp
==============================================================================
--- branches/release/boost/iostreams/device/file_descriptor.hpp	(original)
+++ branches/release/boost/iostreams/device/file_descriptor.hpp	2008-01-13 02:33:37 EST (Sun, 13 Jan 2008)
@@ -32,29 +32,25 @@
 class BOOST_IOSTREAMS_DECL file_descriptor {
 public:
 #ifdef BOOST_IOSTREAMS_WINDOWS
-    typedef void*  handle_type;
+    typedef void*  handle_type;  // A.k.a HANDLE
+#else
+    typedef int    handle_type;
 #endif
     typedef char   char_type;
     struct category
         : seekable_device_tag,
           closable_tag
         { };
-    file_descriptor() : pimpl_(new impl) { }
-    explicit file_descriptor(int fd, bool close_on_exit = false)
-        : pimpl_(new impl(fd, close_on_exit))
-        { }
+    file_descriptor();
+    explicit file_descriptor(handle_type fd, bool close_on_exit = false);
 #ifdef BOOST_IOSTREAMS_WINDOWS
-    explicit file_descriptor(handle_type handle, bool close_on_exit = false)
-        : pimpl_(new impl(handle, close_on_exit))
-        { }
+    explicit file_descriptor(int fd, bool close_on_exit = false);
 #endif
     explicit file_descriptor( const std::string& path,
                               BOOST_IOS::openmode mode =
                                   BOOST_IOS::in | BOOST_IOS::out,
                               BOOST_IOS::openmode base_mode =
-                                  BOOST_IOS::in | BOOST_IOS::out )
-        : pimpl_(new impl)
-    { open(path, mode, base_mode); }
+                                  BOOST_IOS::in | BOOST_IOS::out );
     void open( const std::string& path,
                BOOST_IOS::openmode =
                    BOOST_IOS::in | BOOST_IOS::out,
@@ -65,41 +61,44 @@
     std::streamsize write(const char_type* s, std::streamsize n);
     std::streampos seek(stream_offset off, BOOST_IOS::seekdir way);
     void close();
+    handle_type handle() const { return pimpl_->handle_; }
 private:
     struct impl {
-        impl() : fd_(-1), flags_(0) { }
-        impl(int fd, bool close_on_exit)
-            : fd_(fd), flags_(0)
-        { if (close_on_exit) flags_ |= impl::close_on_exit; }
-    #ifdef BOOST_IOSTREAMS_WINDOWS
-        impl(handle_type handle, bool close_on_exit)
-            : handle_(handle), flags_(has_handle)
+        impl() : 
+            #ifdef BOOST_IOSTREAMS_WINDOWS
+                handle_(reinterpret_cast<handle_type>(-1)), 
+            #else
+                handle_(-1),
+            #endif
+                flags_(0) 
+            { }
+        impl(handle_type fd, bool close_on_exit)
+            : handle_(fd), flags_(0)
         { if (close_on_exit) flags_ |= impl::close_on_exit; }
-    #endif
-        ~impl() {
-            if (flags_ & close_on_exit) close_impl(*this);
-        }
+        ~impl() 
+        { if (flags_ & close_on_exit) close_impl(*this); }
         enum flags {
             close_on_exit = 1,
-            has_handle = 2,
             append = 4
         };
-        int          fd_;
-    #ifdef BOOST_IOSTREAMS_WINDOWS
         handle_type  handle_;
-    #endif
         int          flags_;
     };
     friend struct impl;
 
     static void close_impl(impl&);
+#ifdef BOOST_IOSTREAMS_WINDOWS
+    static handle_type int_to_handle(int fd);
+#endif
 
     shared_ptr<impl> pimpl_;
 };
 
 struct file_descriptor_source : private file_descriptor {
 #ifdef BOOST_IOSTREAMS_WINDOWS
-    typedef void*  handle_type;
+    typedef void*  handle_type;  // A.k.a HANDLE
+#else
+    typedef int    handle_type;
 #endif
     typedef char   char_type;
     struct category
@@ -112,14 +111,14 @@
     using file_descriptor::open;
     using file_descriptor::is_open;
     using file_descriptor::close;
+    using file_descriptor::handle;
     file_descriptor_source() { }
-    explicit file_descriptor_source(int fd, bool close_on_exit = false)
+    explicit file_descriptor_source(handle_type fd, bool close_on_exit = false)
         : file_descriptor(fd, close_on_exit)
         { }
 #ifdef BOOST_IOSTREAMS_WINDOWS
-    explicit file_descriptor_source( handle_type handle,
-                                     bool close_on_exit = false )
-        : file_descriptor(handle, close_on_exit)
+    explicit file_descriptor_source(int fd, bool close_on_exit = false)
+        : file_descriptor(fd, close_on_exit)
         { }
 #endif
     explicit file_descriptor_source( const std::string& path,
@@ -130,7 +129,9 @@
 
 struct file_descriptor_sink : private file_descriptor {
 #ifdef BOOST_IOSTREAMS_WINDOWS
-    typedef void*  handle_type;
+    typedef void*  handle_type;  // A.k.a HANDLE
+#else
+    typedef int    handle_type;
 #endif
     typedef char   char_type;
     struct category
@@ -143,14 +144,14 @@
     using file_descriptor::open;
     using file_descriptor::is_open;
     using file_descriptor::close;
+    using file_descriptor::handle;
     file_descriptor_sink() { }
-    explicit file_descriptor_sink(int fd, bool close_on_exit = false)
+    explicit file_descriptor_sink(handle_type fd, bool close_on_exit = false)
         : file_descriptor(fd, close_on_exit)
         { }
 #ifdef BOOST_IOSTREAMS_WINDOWS
-    explicit file_descriptor_sink( handle_type handle,
-                                   bool close_on_exit = false )
-        : file_descriptor(handle, close_on_exit)
+    explicit file_descriptor_sink(int fd, bool close_on_exit = false)
+        : file_descriptor(fd, close_on_exit)
         { }
 #endif
     explicit file_descriptor_sink( const std::string& path,
Modified: branches/release/boost/iostreams/filter/aggregate.hpp
==============================================================================
--- branches/release/boost/iostreams/filter/aggregate.hpp	(original)
+++ branches/release/boost/iostreams/filter/aggregate.hpp	2008-01-13 02:33:37 EST (Sun, 13 Jan 2008)
@@ -15,10 +15,13 @@
 #include <cassert>
 #include <iterator>                           // back_inserter
 #include <vector>
+#include <boost/iostreams/constants.hpp>      // default_device_buffer_size 
 #include <boost/iostreams/categories.hpp>
 #include <boost/iostreams/detail/char_traits.hpp>
 #include <boost/iostreams/detail/ios.hpp>     // openmode, streamsize.
 #include <boost/iostreams/pipeline.hpp>
+#include <boost/iostreams/read.hpp>           // check_eof 
+#include <boost/iostreams/write.hpp>
 #include <boost/mpl/bool.hpp>
 #include <boost/type_traits/is_convertible.hpp>
 
Modified: branches/release/boost/iostreams/filter/gzip.hpp
==============================================================================
--- branches/release/boost/iostreams/filter/gzip.hpp	(original)
+++ branches/release/boost/iostreams/filter/gzip.hpp	2008-01-13 02:33:37 EST (Sun, 13 Jan 2008)
@@ -134,7 +134,7 @@
                  std::string comment    = "",
                  std::time_t mtime      = 0 )
         : zlib_params(level, method, window_bits, mem_level, strategy),
-          file_name(file_name), mtime(mtime)
+          file_name(file_name), comment(comment), mtime(mtime)
         { }
     std::string  file_name;
     std::string  comment;
Modified: branches/release/boost/iostreams/filter/line.hpp
==============================================================================
--- branches/release/boost/iostreams/filter/line.hpp	(original)
+++ branches/release/boost/iostreams/filter/line.hpp	2008-01-13 02:33:37 EST (Sun, 13 Jan 2008)
@@ -18,7 +18,9 @@
 #include <boost/config.hpp>                        // BOOST_STATIC_CONSTANT.
 #include <boost/iostreams/categories.hpp>
 #include <boost/iostreams/detail/ios.hpp>          // openmode, streamsize.
+#include <boost/iostreams/read.hpp>                // check_eof 
 #include <boost/iostreams/pipeline.hpp>
+#include <boost/iostreams/write.hpp>
 
 // Must come last.
 #include <boost/iostreams/detail/config/disable_warnings.hpp> // VC7.1 C4244.
Modified: branches/release/boost/iostreams/filter/newline.hpp
==============================================================================
--- branches/release/boost/iostreams/filter/newline.hpp	(original)
+++ branches/release/boost/iostreams/filter/newline.hpp	2008-01-13 02:33:37 EST (Sun, 13 Jan 2008)
@@ -19,8 +19,12 @@
 #include <stdexcept>                       // logic_error.
 #include <boost/config.hpp>                // BOOST_STATIC_CONSTANT.
 #include <boost/iostreams/categories.hpp>
-#include <boost/iostreams/detail/char_traits.hpp>
+#include <boost/iostreams/detail/char_traits.hpp>	
+#include <boost/iostreams/detail/ios.hpp>  // BOOST_IOSTREAMS_FAILURE 
+#include <boost/iostreams/read.hpp>        // get 
+#include <boost/iostreams/write.hpp>       // put 
 #include <boost/iostreams/pipeline.hpp>
+#include <boost/iostreams/putback.hpp>
 #include <boost/mpl/bool.hpp>
 #include <boost/type_traits/is_convertible.hpp>
 
Modified: branches/release/boost/iostreams/input_sequence.hpp
==============================================================================
--- branches/release/boost/iostreams/input_sequence.hpp	(original)
+++ branches/release/boost/iostreams/input_sequence.hpp	2008-01-13 02:33:37 EST (Sun, 13 Jan 2008)
@@ -15,6 +15,7 @@
 #include <boost/config.hpp>  // DEDUCED_TYPENAME, MSVC.
 #include <boost/detail/workaround.hpp>
 #include <boost/iostreams/detail/wrap_unwrap.hpp>
+#include <boost/iostreams/operations_fwd.hpp>  // is_custom 
 #include <boost/iostreams/traits.hpp>
 #include <boost/mpl/if.hpp>
 
Modified: branches/release/boost/iostreams/output_sequence.hpp
==============================================================================
--- branches/release/boost/iostreams/output_sequence.hpp	(original)
+++ branches/release/boost/iostreams/output_sequence.hpp	2008-01-13 02:33:37 EST (Sun, 13 Jan 2008)
@@ -15,6 +15,7 @@
 #include <boost/config.hpp>  // DEDUCED_TYPENAME, MSVC.
 #include <boost/detail/workaround.hpp>
 #include <boost/iostreams/detail/wrap_unwrap.hpp>
+#include <boost/iostreams/operations_fwd.hpp>  // is_custom 
 #include <boost/iostreams/traits.hpp>
 #include <boost/mpl/if.hpp>
 
Modified: branches/release/boost/iostreams/positioning.hpp
==============================================================================
--- branches/release/boost/iostreams/positioning.hpp	(original)
+++ branches/release/boost/iostreams/positioning.hpp	2008-01-13 02:33:37 EST (Sun, 13 Jan 2008)
@@ -18,6 +18,7 @@
 #include <boost/cstdint.hpp>
 #include <boost/integer_traits.hpp>
 #include <boost/iostreams/detail/config/codecvt.hpp> // mbstate_t.
+#include <boost/iostreams/detail/config/fpos.hpp>
 #include <boost/iostreams/detail/ios.hpp> // streamoff, streampos.
 
 // Must come last.
@@ -28,74 +29,83 @@
 #endif
 
 namespace boost { namespace iostreams {
+                    
+//------------------Definition of stream_offset-------------------------------//
 
 typedef boost::intmax_t stream_offset;
 
+//------------------Definition of stream_offset_to_streamoff------------------//
+
 inline std::streamoff stream_offset_to_streamoff(stream_offset off)
 { return static_cast<stream_offset>(off); }
 
-template<typename PosType> // Hande custom pos_type's.
+//------------------Definition of offset_to_position--------------------------//
+
+# ifndef BOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS
+
+inline std::streampos offset_to_position(stream_offset off) { return off; }
+
+# else // # ifndef BOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS
+
+inline std::streampos offset_to_position(stream_offset off)
+{ return std::streampos(std::mbstate_t(), off); }
+
+# endif // # ifndef BOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS
+
+//------------------Definition of position_to_offset--------------------------//
+
+// Hande custom pos_type's
+template<typename PosType> 
 inline stream_offset position_to_offset(PosType pos)
 { return std::streamoff(pos); }
 
-#if ((defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER)) && \
-     !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) \
-     && !defined(__QNX__) \
-   /**/
+# ifndef BOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS
 
-        /* Dinkumware */
+inline stream_offset position_to_offset(std::streampos pos) { return pos; }
 
-inline std::streampos offset_to_position(stream_offset off)
-{
-    // Use implementation-specific constructor.
-    return std::streampos(std::mbstate_t(), off);
-}
+# else // # ifndef BOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS
+
+// In the Dinkumware standard library, a std::streampos consists of two stream
+// offsets -- _Fpos, of type std::fpos_t, and _Myoff, of type std::streamoff --
+// together with a conversion state. A std::streampos is converted to a 
+// boost::iostreams::stream_offset by extracting the two stream offsets and
+// summing them. The value of _Fpos can be extracted using the implementation-
+// defined member functions seekpos() or get_fpos_t(), depending on the 
+// Dinkumware version. The value of _Myoff cannot be extracted directly, but can
+// be calculated as the difference between the result of converting the 
+// std::fpos to a std::streamoff and the result of converting the member _Fpos
+// to a long. The latter operation is accomplished with the macro _FPOSOFF, 
+// which works correctly on platforms where std::fpos_t is an integral type and 
+// platforms where it is a struct
 
+// Converts a std::fpos_t to a stream_offset
 inline stream_offset fpos_t_to_offset(std::fpos_t pos)
-{ // Helper function.
-#if defined(_POSIX_) || (_INTEGRAL_MAX_BITS >= 64)
+{
+#  if defined(_POSIX_) || (_INTEGRAL_MAX_BITS >= 64) || defined(__IBMCPP__)
     return pos;
-#else
+#  else
     return _FPOSOFF(pos);
-#endif
+#  endif
 }
 
-# if defined(_CPPLIB_VER) //--------------------------------------------------//
-
-        /* Recent Dinkumware */
-
-inline stream_offset position_to_offset(std::streampos pos)
+// Extracts the member _Fpos from a std::fpos
+inline std::fpos_t streampos_to_fpos_t(std::streampos pos)
 {
-    // Use implementation-specific member function seekpos().
-    return fpos_t_to_offset(pos.seekpos()) +
-           static_cast<stream_offset>(static_cast<std::streamoff>(pos)) -
-           static_cast<stream_offset>(_FPOSOFF(pos.seekpos()));
+#  if defined (_CPPLIB_VER) || defined(__IBMCPP__)
+    return pos.seekpos();
+#  else
+    return pos.get_fpos_t();
+#  endif
 }
 
-# else // # if defined(_CPPLIB_VER) //----------------------------------------//
-
-        /* Old Dinkumware */
-
 inline stream_offset position_to_offset(std::streampos pos)
 {
-    // use implementation-specific member function get_fpos_t().
-    return fpos_t_to_offset(pos.get_fpos_t()) +
+    return fpos_t_to_offset(streampos_to_fpos_t(pos)) +
            static_cast<stream_offset>(static_cast<std::streamoff>(pos)) -
-           static_cast<stream_offset>(
-               static_cast<std::streamoff>(pos.get_fpos_t())
-           );
+           static_cast<stream_offset>(_FPOSOFF(streampos_to_fpos_t(pos)));
 }
 
-# endif // # if defined(_CPPLIB_VER) //---------------------------------------//
-#else // Dinkumware //--------------------------------------------------------//
-
-        /* Non-Dinkumware */
-
-inline std::streampos offset_to_position(stream_offset off) { return off; }
-
-inline stream_offset position_to_offset(std::streampos pos) { return pos; }
-
-#endif // Dinkumware //-------------------------------------------------------//
+# endif // # ifndef BOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS 
 
 } } // End namespaces iostreams, boost.
 
Modified: branches/release/boost/iostreams/restrict.hpp
==============================================================================
--- branches/release/boost/iostreams/restrict.hpp	(original)
+++ branches/release/boost/iostreams/restrict.hpp	2008-01-13 02:33:37 EST (Sun, 13 Jan 2008)
@@ -1,443 +1,24 @@
-// (C) Copyright Jonathan Turkanis 2005.
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
-
-// See http://www.boost.org/libs/iostreams for documentation.
+/*
+ * Distributed under the Boost Software License, Version 1.0.(See accompanying 
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
+ * 
+ * See http://www.boost.org/libs/iostreams for documentation.
+ *
+ * File:        boost/iostreams/detail/restrict.hpp
+ * Date:        Sun Jan 06 12:57:30 MST 2008
+ * Copyright:   2004-2007 Jonathan Turkanis
+ * Author:      Jonathan Turkanis
+ *
+ * Defines the class template boost::iostreams::restriction and the 
+ * overloaded function template boost::iostreams::restrict
+ */
 
 #ifndef BOOST_IOSTREAMS_RESTRICT_HPP_INCLUDED
 #define BOOST_IOSTREAMS_RESTRICT_HPP_INCLUDED
 
-#if defined(_MSC_VER) && (_MSC_VER >= 1020)
-# pragma once
-#endif
-
-#include <algorithm>          // min.
-#include <utility>            // pair.
-#include <boost/cstdint.hpp>  // intmax_t.
-#include <boost/config.hpp>   // DEDUCED_TYPENAME.
-#include <boost/iostreams/categories.hpp>
-#include <boost/iostreams/char_traits.hpp>
-#include <boost/iostreams/detail/adapter/device_adapter.hpp>
-#include <boost/iostreams/detail/adapter/filter_adapter.hpp>
-#include <boost/iostreams/detail/call_traits.hpp>
-#include <boost/iostreams/detail/enable_if_stream.hpp>
-#include <boost/iostreams/detail/error.hpp>
-#include <boost/iostreams/detail/ios.hpp>     // failure.
-#include <boost/iostreams/detail/select.hpp>
-#include <boost/iostreams/operations.hpp>
-#include <boost/iostreams/skip.hpp>
-#include <boost/iostreams/traits.hpp>         // mode_of, is_direct.
-#include <boost/mpl/bool.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_convertible.hpp>
-
-#include <boost/iostreams/detail/config/disable_warnings.hpp>
-
-namespace boost { namespace iostreams {
-
-namespace detail {
-
-//
-// Template name: restricted_indirect_device.
-// Description: Provides an restricted view of an indirect Device.
-// Template paramters:
-//      Device - An indirect model of Device that models either Source or
-//          SeekableDevice.
-//
-template<typename Device>
-class restricted_indirect_device : public device_adapter<Device> {
-private:
-    typedef typename detail::param_type<Device>::type  param_type;
-public:
-    typedef typename char_type_of<Device>::type  char_type;
-    typedef typename mode_of<Device>::type       mode;
-    BOOST_STATIC_ASSERT(!(is_convertible<mode, detail::two_sequence>::value));
-    struct category
-        : mode,
-          device_tag,
-          closable_tag,
-          flushable_tag,
-          localizable_tag,
-          optimally_buffered_tag
-        { };
-    restricted_indirect_device( param_type dev, stream_offset off,
-                                stream_offset len = -1 );
-    std::streamsize read(char_type* s, std::streamsize n);
-    std::streamsize write(const char_type* s, std::streamsize n);
-    std::streampos seek(stream_offset off, BOOST_IOS::seekdir way);
-private:
-    stream_offset beg_, pos_, end_;
-};
-
-//
-// Template name: restricted_direct_device.
-// Description: Provides an restricted view of a Direct Device.
-// Template paramters:
-//      Device - A model of Direct and Device.
-//
-template<typename Device>
-class restricted_direct_device : public device_adapter<Device> {
-public:
-    typedef typename char_type_of<Device>::type  char_type;
-    typedef std::pair<char_type*, char_type*>    pair_type;
-    typedef typename mode_of<Device>::type       mode;
-    BOOST_STATIC_ASSERT(!(is_convertible<mode, detail::two_sequence>::value));
-    struct category
-        : mode_of<Device>::type,
-          device_tag,
-          direct_tag,
-          closable_tag,
-          localizable_tag
-        { };
-    restricted_direct_device( const Device& dev, stream_offset off,
-                              stream_offset len = -1 );
-    pair_type input_sequence();
-    pair_type output_sequence();
-private:
-    pair_type sequence(mpl::true_);
-    pair_type sequence(mpl::false_);
-    char_type *beg_, *end_;
-};
-
-//
-// Template name: restricted_filter.
-// Description: Provides an restricted view of a Filter.
-// Template paramters:
-//      Filter - An indirect model of Filter.
-//
-template<typename Filter>
-class restricted_filter : public filter_adapter<Filter> {
-public:
-    typedef typename char_type_of<Filter>::type char_type;
-    typedef typename mode_of<Filter>::type      mode;
-    BOOST_STATIC_ASSERT(!(is_convertible<mode, detail::two_sequence>::value));
-    struct category
-        : mode,
-          filter_tag,
-          multichar_tag,
-          closable_tag,
-          localizable_tag,
-          optimally_buffered_tag
-        { };
-    restricted_filter( const Filter& flt, stream_offset off, 
-                       stream_offset len = -1 );
-
-    template<typename Source>
-    std::streamsize read(Source& src, char_type* s, std::streamsize n)
-    {
-        using namespace std;
-        if (!open_)
-            open(src, BOOST_IOS::in);
-        std::streamsize amt =
-            end_ != -1 ?
-                (std::min) (n, static_cast<std::streamsize>(end_ - pos_)) :
-                n;
-        std::streamsize result = 
-            iostreams::read(this->component(), src, s, amt);
-        if (result != -1)
-            pos_ += result;
-        return result;
-    }
-
-    template<typename Sink>
-    std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
-    {
-        if (!open_)
-            open(snk, BOOST_IOS::out);
-        if (end_ != -1 && pos_ + n >= end_)
-            bad_write();
-        std::streamsize result = 
-            iostreams::write(this->component(), snk, s, n);
-        pos_ += result;
-        return result;
-    }
-
-    template<typename Device>
-    std::streampos seek(Device& dev, stream_offset off, BOOST_IOS::seekdir way)
-    {
-        stream_offset next;
-        if (way == BOOST_IOS::beg) {
-            next = beg_ + off;
-        } else if (way == BOOST_IOS::cur) {
-            next = pos_ + off;
-        } else if (end_ != -1) {
-            next = end_ + off;
-        } else {
-            // Restriction is half-open; seek relative to the actual end.
-            pos_ = this->component().seek(dev, off, BOOST_IOS::end);
-            if (pos_ < beg_)
-                bad_seek();
-            return offset_to_position(pos_ - beg_);
-        }
-        if (next < beg_ || end_ != -1 && next >= end_)
-            bad_seek();
-        pos_ = this->component().seek(dev, next, BOOST_IOS::cur);
-        return offset_to_position(pos_ - beg_);
-    }
-
-    template<typename Device>
-    void close(Device& dev) 
-    { 
-        open_ = false;
-        detail::close_all(this->component(), dev); 
-    }
-
-    template<typename Device>
-    void close(Device& dev, BOOST_IOS::openmode which) 
-    { 
-        open_ = false;
-        iostreams::close(this->component(), dev, which); 
-    }
-private:
-    template<typename Device>
-    void open(Device& dev, BOOST_IOS::openmode which)
-    {
-        typedef typename is_convertible<mode, dual_use>::type is_dual_use;
-        open_ = true;
-        which = is_dual_use() ? which : (BOOST_IOS::in | BOOST_IOS::out);
-        iostreams::skip(this->component(), dev, beg_, which);
-    }
-
-    stream_offset  beg_, pos_, end_;
-    bool           open_;
-};
-
-template<typename T>
-struct restriction_traits
-    : iostreams::select<  // Disambiguation for Tru64.
-          is_filter<T>,  restricted_filter<T>,
-          is_direct<T>,  restricted_direct_device<T>,
-          else_,         restricted_indirect_device<T>
-      >
-    { };
-
-} // End namespace detail.
-
-template<typename T>
-struct restriction : public detail::restriction_traits<T>::type {
-    typedef typename detail::param_type<T>::type          param_type;
-    typedef typename detail::restriction_traits<T>::type  base_type;
-    restriction(param_type t, stream_offset off, stream_offset len = -1)
-        : base_type(t, off, len)
-        { }
-};
-
-//--------------Implementation of restrict------------------------------------//
-
-// Note: The following workarounds are patterned after resolve.hpp. It has not
-// yet been confirmed that they are necessary.
-
-#ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //-------------------------//
-# ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-------------------------------//
-
-template<typename T>
-restriction<T> restrict( const T& t, stream_offset off, stream_offset len = -1
-                         BOOST_IOSTREAMS_DISABLE_IF_STREAM(T) )
-{ return restriction<T>(t, off, len); }
-
-template<typename Ch, typename Tr>
-restriction< std::basic_streambuf<Ch, Tr> >
-restrict(std::basic_streambuf<Ch, Tr>& sb, stream_offset off, stream_offset len = -1)
-{ return restriction< std::basic_streambuf<Ch, Tr> >(sb, off, len); }
-
-template<typename Ch, typename Tr>
-restriction< std::basic_istream<Ch, Tr> >
-restrict(std::basic_istream<Ch, Tr>& is, stream_offset off, stream_offset len = -1)
-{ return restriction< std::basic_istream<Ch, Tr> >(is, off, len); }
-
-template<typename Ch, typename Tr>
-restriction< std::basic_ostream<Ch, Tr> >
-restrict(std::basic_ostream<Ch, Tr>& os, stream_offset off, stream_offset len = -1)
-{ return restriction< std::basic_ostream<Ch, Tr> >(os, off, len); }
-
-template<typename Ch, typename Tr>
-restriction< std::basic_iostream<Ch, Tr> >
-restrict(std::basic_iostream<Ch, Tr>& io, stream_offset off, stream_offset len = -1)
-{ return restriction< std::basic_iostream<Ch, Tr> >(io, off, len); }
-
-# else // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //---------------------//
-
-template<typename T>
-restriction<T> restrict( const T& t, stream_offset off, stream_offset len = -1
-                         BOOST_IOSTREAMS_DISABLE_IF_STREAM(T) )
-{ return restriction<T>(t, off, len); }
-
-restriction<std::streambuf> 
-restrict(std::streambuf& sb, stream_offset off, stream_offset len = -1)
-{ return restriction<std::streambuf>(sb, off, len); }
-
-restriction<std::istream> 
-restrict(std::istream<Ch, Tr>& is, stream_offset off, stream_offset len = -1)
-{ return restriction<std::istream>(is, off, len); }
-
-restriction<std::ostream> 
-restrict(std::ostream<Ch, Tr>& os, stream_offset off, stream_offset len = -1)
-{ return restriction<std::ostream>(os, off, len); }
-
-restriction<std::iostream> 
-restrict(std::iostream<Ch, Tr>& io, stream_offset off, stream_offset len = -1)
-{ return restriction<std::iostream>(io, off, len); }
-
-# endif // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------//
-#else // #ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //----------------//
-
-template<typename T>
-restriction<T> 
-restrict(const T& t, stream_offset off, stream_offset len, mpl::true_)
-{   // Bad overload resolution.
-    return restriction<T>(const_cast<T&>(t, off, len));
-}
-
-template<typename T>
-restriction<T> 
-restrict(const T& t, stream_offset off, stream_offset len, mpl::false_)
-{ return restriction<T>(t, off, len); }
-
-template<typename T>
-restriction<T> 
-restrict( const T& t, stream_offset off, stream_offset len = -1
-          BOOST_IOSTREAMS_DISABLE_IF_STREAM(T) )
-{ return restrict(t, off, len, is_std_io<T>()); }
-
-# if !BOOST_WORKAROUND(__BORLANDC__, < 0x600) && \
-     !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) && \
-     !defined(__GNUC__) // ---------------------------------------------------//
-
-template<typename T>
-restriction<T>
-restrict(T& t, stream_offset off, stream_offset len = -1)
-{ return restriction<T>(t, off, len); }
-
-# endif // Borland 5.x, VC6-7.0 or GCC 2.9x //--------------------------------//
-#endif // #ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //---------------//
-//----------------------------------------------------------------------------//
-
-namespace detail {
-
-//--------------Implementation of restricted_indirect_device------------------//
-
-template<typename Device>
-restricted_indirect_device<Device>::restricted_indirect_device
-    (param_type dev, stream_offset off, stream_offset len)
-    : device_adapter<Device>(dev), beg_(off), pos_(off), 
-      end_(len != -1 ? off + len : -1)
-{
-    if (len < -1 || off < 0)
-        throw BOOST_IOSTREAMS_FAILURE("bad offset");
-    iostreams::skip(this->component(), off);
-}
-
-template<typename Device>
-inline std::streamsize restricted_indirect_device<Device>::read
-    (char_type* s, std::streamsize n)
-{
-    using namespace std;
-    std::streamsize amt =
-        end_ != -1 ?
-            (std::min) (n, static_cast<std::streamsize>(end_ - pos_)) :
-            n;
-    std::streamsize result = iostreams::read(this->component(), s, amt);
-    if (result != -1)
-        pos_ += result;
-    return result;
-}
-
-template<typename Device>
-inline std::streamsize restricted_indirect_device<Device>::write
-    (const char_type* s, std::streamsize n)
-{
-    if (end_ != -1 && pos_ + n >= end_)
-        bad_write();
-    std::streamsize result = iostreams::write(this->component(), s, n);
-    pos_ += result;
-    return result;
-}
-
-template<typename Device>
-std::streampos restricted_indirect_device<Device>::seek
-    (stream_offset off, BOOST_IOS::seekdir way)
-{
-    stream_offset next;
-    if (way == BOOST_IOS::beg) {
-        next = beg_ + off;
-    } else if (way == BOOST_IOS::cur) {
-        next = pos_ + off;
-    } else if (end_ != -1) {
-        next = end_ + off;
-    } else {
-        // Restriction is half-open; seek relative to the actual end.
-        pos_ = iostreams::seek(this->component(), off, BOOST_IOS::end);
-        if (pos_ < beg_)
-            bad_seek();
-        return offset_to_position(pos_ - beg_);
-    }
-    if (next < beg_ || end_ != -1 && next >= end_)
-        bad_seek();
-    pos_ = iostreams::seek(this->component(), next - pos_, BOOST_IOS::cur);
-    return offset_to_position(pos_ - beg_);
-}
-
-//--------------Implementation of restricted_direct_device--------------------//
-
-template<typename Device>
-restricted_direct_device<Device>::restricted_direct_device
-    (const Device& dev, stream_offset off, stream_offset len)
-    : device_adapter<Device>(dev), beg_(0), end_(0)
-{
-    std::pair<char_type*, char_type*> seq =
-        sequence(is_convertible<category, input>());
-    if ( off < 0 || len < -1 || 
-         len != -1 && off + len > seq.second - seq.first )
-    {
-        throw BOOST_IOSTREAMS_FAILURE("bad offset");
-    }
-    beg_ = seq.first + off;
-    end_ = len != -1 ? 
-        seq.first + off + len :
-        seq.second;
-}
-
-template<typename Device>
-typename restricted_direct_device<Device>::pair_type
-restricted_direct_device<Device>::input_sequence()
-{
-    BOOST_STATIC_ASSERT((is_convertible<category, input>::value));
-    return std::make_pair(beg_, end_);
-}
-
-template<typename Device>
-typename restricted_direct_device<Device>::pair_type
-restricted_direct_device<Device>::output_sequence()
-{
-    BOOST_STATIC_ASSERT((is_convertible<category, output>::value));
-    return std::make_pair(beg_, end_);
-}
-
-template<typename Device>
-typename restricted_direct_device<Device>::pair_type
-restricted_direct_device<Device>::sequence(mpl::true_)
-{ return iostreams::input_sequence(this->component()); }
-
-template<typename Device>
-typename restricted_direct_device<Device>::pair_type
-restricted_direct_device<Device>::sequence(mpl::false_)
-{ return iostreams::output_sequence(this->component()); }
-
-//--------------Implementation of restricted_filter---------------------------//
-
-template<typename Filter>
-restricted_filter<Filter>::restricted_filter
-    (const Filter& flt, stream_offset off, stream_offset len)
-    : filter_adapter<Filter>(flt), beg_(off),
-      pos_(off), end_(len != -1 ? off + len : -1), open_(false)
-{
-    if (len < -1 || off < 0)
-        throw BOOST_IOSTREAMS_FAILURE("bad offset");
-}
-
-} // End namespace detail.
-
-} } // End namespaces iostreams, boost.
-
+#include <boost/iostreams/detail/restrict_impl.hpp>
+#define BOOST_IOSTREAMS_RESTRICT restrict
+#include <boost/iostreams/detail/restrict_impl.hpp>
+#undef BOOST_IOSTREAMS_RESTRICT
 
 #endif // #ifndef BOOST_IOSTREAMS_RESTRICT_HPP_INCLUDED
Modified: branches/release/libs/iostreams/src/file_descriptor.cpp
==============================================================================
--- branches/release/libs/iostreams/src/file_descriptor.cpp	(original)
+++ branches/release/libs/iostreams/src/file_descriptor.cpp	2008-01-13 02:33:37 EST (Sun, 13 Jan 2008)
@@ -44,6 +44,24 @@
 
 //------------------Implementation of file_descriptor-------------------------//
 
+file_descriptor::file_descriptor() : pimpl_(new impl) { }
+
+file_descriptor::file_descriptor(handle_type fd, bool close_on_exit)
+    : pimpl_(new impl(fd, close_on_exit))
+    { }
+
+#ifdef BOOST_IOSTREAMS_WINDOWS
+    file_descriptor::file_descriptor(int fd, bool close_on_exit)
+        : pimpl_(new impl(int_to_handle(fd), close_on_exit))
+        { }
+#endif
+
+file_descriptor::file_descriptor( const std::string& path,
+                                  BOOST_IOS::openmode mode,
+                                  BOOST_IOS::openmode base_mode )
+    : pimpl_(new impl)
+{ open(path, mode, base_mode); }
+
 void file_descriptor::open
     ( const std::string& path, BOOST_IOS::openmode m,
       BOOST_IOS::openmode base )
@@ -88,7 +106,7 @@
                        NULL );                 // hTemplateFile
     if (handle != INVALID_HANDLE_VALUE) {
         pimpl_->handle_ = handle;
-        pimpl_->flags_ |= impl::close_on_exit | impl::has_handle;
+        pimpl_->flags_ |= impl::close_on_exit;
     } else {
         pimpl_->flags_ = 0;
         throw BOOST_IOSTREAMS_FAILURE("bad open");
@@ -131,7 +149,7 @@
     if (fd == -1) {
         throw BOOST_IOSTREAMS_FAILURE("bad open");
     } else {
-        pimpl_->fd_ = fd;
+        pimpl_->handle_ = fd;
         pimpl_->flags_ = impl::close_on_exit;
     }
 #endif // #ifndef BOOST_IOSTREAMS_WINDOWS //----------------------------------//
@@ -140,43 +158,41 @@
 std::streamsize file_descriptor::read(char_type* s, std::streamsize n)
 {
 #ifdef BOOST_IOSTREAMS_WINDOWS
-    if (pimpl_->flags_ & impl::has_handle) {
-        DWORD result;
-        if (!::ReadFile(pimpl_->handle_, s, n, &result, NULL))
-            throw detail::bad_read();
-        return static_cast<std::streamsize>(result);
-    }
-#endif
+    DWORD result;
+    if (!::ReadFile(pimpl_->handle_, s, n, &result, NULL))
+        throw detail::bad_read();
+    return static_cast<std::streamsize>(result);
+#else // #ifdef BOOST_IOSTREAMS_WINDOWS
     errno = 0;
-    std::streamsize result = BOOST_IOSTREAMS_FD_READ(pimpl_->fd_, s, n);
+    std::streamsize result = BOOST_IOSTREAMS_FD_READ(pimpl_->handle_, s, n);
     if (errno != 0)
         throw detail::bad_read();
     return result == 0 ? -1 : result;
+#endif // #ifdef BOOST_IOSTREAMS_WINDOWS
 }
 
 std::streamsize file_descriptor::write(const char_type* s, std::streamsize n)
 {
 #ifdef BOOST_IOSTREAMS_WINDOWS
-    if (pimpl_->flags_ & impl::has_handle) {
-        if (pimpl_->flags_ & impl::append) {
-            DWORD const dwResult =
-                ::SetFilePointer(pimpl_->handle_, 0, NULL, FILE_END);
-            if ( dwResult == INVALID_SET_FILE_POINTER &&
-                 ::GetLastError() != NO_ERROR )
-            {
-                throw detail::bad_seek();
-            }
+    if (pimpl_->flags_ & impl::append) {
+        DWORD const dwResult =
+            ::SetFilePointer(pimpl_->handle_, 0, NULL, FILE_END);
+        if ( dwResult == INVALID_SET_FILE_POINTER &&
+             ::GetLastError() != NO_ERROR )
+        {
+            throw detail::bad_seek();
         }
-        DWORD ignore;
-        if (!::WriteFile(pimpl_->handle_, s, n, &ignore, NULL))
-            throw detail::bad_write();
-        return n;
     }
-#endif
-    int amt = BOOST_IOSTREAMS_FD_WRITE(pimpl_->fd_, s, n);
+    DWORD ignore;
+    if (!::WriteFile(pimpl_->handle_, s, n, &ignore, NULL))
+        throw detail::bad_write();
+    return n;
+#else // #ifdef BOOST_IOSTREAMS_WINDOWS
+    int amt = BOOST_IOSTREAMS_FD_WRITE(pimpl_->handle_, s, n);
     if (amt < n)
         throw detail::bad_write(); // Handles blocking fd's only.
     return n;
+#endif // #ifdef BOOST_IOSTREAMS_WINDOWS
 }
 
 std::streampos file_descriptor::seek
@@ -184,29 +200,27 @@
 {
     using namespace std;
 #ifdef BOOST_IOSTREAMS_WINDOWS
-    if (pimpl_->flags_ & impl::has_handle) {
-        LONG lDistanceToMove = static_cast<LONG>(off & 0xffffffff);
-        LONG lDistanceToMoveHigh = static_cast<LONG>(off >> 32);
-        DWORD dwResultLow =
-            ::SetFilePointer( pimpl_->handle_,
-                              lDistanceToMove,
-                              &lDistanceToMoveHigh,
-                              way == BOOST_IOS::beg ?
-                                  FILE_BEGIN :
-                                  way == BOOST_IOS::cur ?
-                                    FILE_CURRENT :
-                                    FILE_END );
-        if ( dwResultLow == INVALID_SET_FILE_POINTER &&
-             ::GetLastError() != NO_ERROR )
-        {
-            throw detail::bad_seek();
-        } else {
-           return offset_to_position(
- 	   	              (stream_offset(lDistanceToMoveHigh) << 32) + dwResultLow
-                  );
-        }
+    LONG lDistanceToMove = static_cast<LONG>(off & 0xffffffff);
+    LONG lDistanceToMoveHigh = static_cast<LONG>(off >> 32);
+    DWORD dwResultLow =
+        ::SetFilePointer( pimpl_->handle_,
+                          lDistanceToMove,
+                          &lDistanceToMoveHigh,
+                          way == BOOST_IOS::beg ?
+                              FILE_BEGIN :
+                              way == BOOST_IOS::cur ?
+                                FILE_CURRENT :
+                                FILE_END );
+    if ( dwResultLow == INVALID_SET_FILE_POINTER &&
+         ::GetLastError() != NO_ERROR )
+    {
+        throw detail::bad_seek();
+    } else {
+       return offset_to_position(
+   	              (stream_offset(lDistanceToMoveHigh) << 32) + dwResultLow
+              );
     }
-#endif // #ifdef BOOST_IOSTREAMS_WINDOWS
+#else // #ifdef BOOST_IOSTREAMS_WINDOWS
     if ( off > integer_traits<BOOST_IOSTREAMS_FD_OFFSET>::const_max ||
          off < integer_traits<BOOST_IOSTREAMS_FD_OFFSET>::const_min )
     {
@@ -214,7 +228,7 @@
     }
     stream_offset result =
         BOOST_IOSTREAMS_FD_SEEK(
-            pimpl_->fd_,
+            pimpl_->handle_,
             static_cast<BOOST_IOSTREAMS_FD_OFFSET>(off),
             ( way == BOOST_IOS::beg ?
                   SEEK_SET :
@@ -225,6 +239,7 @@
     if (result == -1)
         throw detail::bad_seek();
     return offset_to_position(result);
+#endif // #ifdef BOOST_IOSTREAMS_WINDOWS
 }
 
 void file_descriptor::close() { close_impl(*pimpl_); }
@@ -232,20 +247,28 @@
 void file_descriptor::close_impl(impl& i)
 {
 #ifdef BOOST_IOSTREAMS_WINDOWS
-    if (i.flags_ & impl::has_handle) {
+    if (i.handle_ != reinterpret_cast<handle_type>(-1)) {
         if (!::CloseHandle(i.handle_))
             throw BOOST_IOSTREAMS_FAILURE("bad close");
-        i.fd_ = -1;
+        i.handle_ = reinterpret_cast<handle_type>(-1);
         i.flags_ = 0;
         return;
     }
-#endif
-    if (i.fd_ != -1) {
-        if (BOOST_IOSTREAMS_FD_CLOSE(i.fd_) == -1)
+#else // #ifdef BOOST_IOSTREAMS_WINDOWS
+    if (i.handle_ != -1) {
+        if (BOOST_IOSTREAMS_FD_CLOSE(i.handle_) == -1)
             throw BOOST_IOSTREAMS_FAILURE("bad close");
-        i.fd_ = -1;
+        i.handle_ = -1;
         i.flags_ = 0;
     }
+#endif // #ifdef BOOST_IOSTREAMS_WINDOWS
+}
+
+#ifdef BOOST_IOSTREAMS_WINDOWS
+file_descriptor::handle_type file_descriptor::int_to_handle(int fd)
+{
+    return reinterpret_cast<handle_type>(_get_osfhandle(fd));
 }
+#endif
 
 } } // End namespaces iostreams, boost.
Modified: branches/release/libs/iostreams/test/Jamfile.v2
==============================================================================
--- branches/release/libs/iostreams/test/Jamfile.v2	(original)
+++ branches/release/libs/iostreams/test/Jamfile.v2	2008-01-13 02:33:37 EST (Sun, 13 Jan 2008)
@@ -22,8 +22,9 @@
             : # command
             : # input files
             : # build requirements
+                <toolset>msvc:<define>_CRT_SECURE_NO_DEPRECATE
+                <toolset>msvc:<define>_SCL_SECURE_NO_DEPRECATE
                 <toolset>msvc,<stdlib>stlport:<runtime-link>static
-                <toolset>msvc:<cxxflags>"-wd4996"
                 <toolset>cw-9.3,<os>darwin:<runtime-link>static
                 <define>BOOST_IOSTREAMS_NO_LIB
                 <link>shared:<define>BOOST_IOSTREAMS_DYN_LINK=1
@@ -38,7 +39,8 @@
           [ test-iostreams close_test.cpp ]
           [ test-iostreams 
                 code_converter_test.cpp    
-                detail/utf8_codecvt_facet.cpp ]
+                detail/utf8_codecvt_facet.cpp : <link>static ]
+          [ test-iostreams combine_test.cpp ]
           [ test-iostreams compose_test.cpp ]
           [ test-iostreams component_access_test.cpp ]
           [ test-iostreams copy_test.cpp ]
@@ -47,17 +49,15 @@
           [ test-iostreams example_test.cpp ]
           [ test-iostreams execute_test.cpp ]
           [ test-iostreams file_test.cpp ]
-          [ test-iostreams 
-                file_descriptor_test.cpp 
-                ../build//boost_iostreams : <link>static ]
+          [ test-iostreams file_descriptor_test.cpp
+                ../src/file_descriptor.cpp : <link>static ]
           [ test-iostreams filtering_stream_test.cpp ]
           [ test-iostreams finite_state_filter_test.cpp ]
           [ test-iostreams flush_test.cpp ]
           [ test-iostreams invert_test.cpp ]
           [ test-iostreams line_filter_test.cpp ]
-          [ test-iostreams 
-                mapped_file_test.cpp 
-                ../build//boost_iostreams : <link>static ]
+          [ test-iostreams mapped_file_test.cpp 
+                ../src/mapped_file.cpp : <link>static ]
           [ test-iostreams newline_test.cpp ]
           [ test-iostreams null_test.cpp ]
           [ test-iostreams operation_sequence_test.cpp ]
@@ -69,6 +69,7 @@
           [ test-iostreams seekable_file_test.cpp ]
           [ test-iostreams seekable_filter_test.cpp ]
           [ test-iostreams sequence_test.cpp ]
+          [ test-iostreams slice_test.cpp ]
           [ test-iostreams stdio_filter_test.cpp ]
           [ test-iostreams stream_offset_32bit_test.cpp ]
           [ test-iostreams stream_offset_64bit_test.cpp ]
@@ -83,18 +84,20 @@
           all-tests += 
               [ test-iostreams 
                     large_file_test.cpp 
-                    ../build//boost_iostreams 
+                    ../src/file_descriptor.cpp
+                    ../src/mapped_file.cpp
                   : <define>LARGE_FILE_KEEP=$(LARGE_FILE_KEEP)
-                    $(KEEP) ] ;
+                    <link>static ] ;
       }
       if $(LARGE_FILE_TEMP)
       {
           all-tests += 
               [ test-iostreams 
                     large_file_test.cpp 
-                    ../build//boost_iostreams 
+                    ../src/file_descriptor.cpp
+                    ../src/mapped_file.cpp
                   : <define>LARGE_FILE_TEMP=$(LARGE_FILE_TEMP)
-                    $(KEEP) ] ;
+                    <link>static ] ;
       }
       if ! $(NO_BZIP2)
       {     
Modified: branches/release/libs/iostreams/test/close_test.cpp
==============================================================================
--- branches/release/libs/iostreams/test/close_test.cpp	(original)
+++ branches/release/libs/iostreams/test/close_test.cpp	2008-01-13 02:33:37 EST (Sun, 13 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
@@ -15,13 +15,7 @@
  */
 
 #include <boost/iostreams/chain.hpp>
-#include <boost/iostreams/combine.hpp>
-#include <boost/iostreams/compose.hpp>
-#include <boost/iostreams/filter/symmetric.hpp>
-#include <boost/iostreams/invert.hpp>
-#include <boost/iostreams/restrict.hpp>
 #include <boost/iostreams/stream.hpp>
-#include <boost/iostreams/tee.hpp>
 #include <boost/test/test_tools.hpp>
 #include <boost/test/unit_test.hpp>  
 #include "detail/closable.hpp"
@@ -506,905 +500,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 +508,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: branches/release/libs/iostreams/test/compose_test.cpp
==============================================================================
--- branches/release/libs/iostreams/test/compose_test.cpp	(original)
+++ branches/release/libs/iostreams/test/compose_test.cpp	2008-01-13 02:33:37 EST (Sun, 13 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: branches/release/libs/iostreams/test/invert_test.cpp
==============================================================================
--- branches/release/libs/iostreams/test/invert_test.cpp	(original)
+++ branches/release/libs/iostreams/test/invert_test.cpp	2008-01-13 02:33:37 EST (Sun, 13 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: branches/release/libs/iostreams/test/large_file_test.cpp
==============================================================================
--- branches/release/libs/iostreams/test/large_file_test.cpp	(original)
+++ branches/release/libs/iostreams/test/large_file_test.cpp	2008-01-13 02:33:37 EST (Sun, 13 Jan 2008)
@@ -252,7 +252,7 @@
         return false;
     }
 
-# if !BOOST_WORKAROUND(__BORLANDC__, == 0x582)
+# if !defined(__BORLANDC__) || __BORLANDC__ < 0x582 || __BORLANDC__ >= 0x592
 
     // Close handle; all further access is via mapped_file
     CloseHandle(hnd);
@@ -260,7 +260,7 @@
     // Initialize file data
     return map_large_file();
 
-# else // Borland 5.8.2
+# else // Borland >= 5.8.2 and Borland < 5.9.2
 
     // Initialize file data (very slow, even though only 9 writes are required)
     for (stream_offset z = 0; z <= 8; ++z) {
@@ -292,7 +292,7 @@
     CloseHandle(hnd);
         return true;
 
-# endif // Borland 5.8.2 workaround
+# endif // Borland workaround
 #else // #ifdef BOOST_IOSTREAMS_WINDOWS
 
     // Create file
Modified: branches/release/libs/iostreams/test/operation_sequence_test.cpp
==============================================================================
--- branches/release/libs/iostreams/test/operation_sequence_test.cpp	(original)
+++ branches/release/libs/iostreams/test/operation_sequence_test.cpp	2008-01-13 02:33:37 EST (Sun, 13 Jan 2008)
@@ -4,9 +4,8 @@
  * 
  * See http://www.boost.org/libs/iostreams for documentation.
  *
- * 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.
+ * Tests the facilities defined in the header
+ * libs/iostreams/test/detail/operation_sequence.hpp
  *
  * File:        libs/iostreams/test/operation_sequence_test.cpp
  * Date:        Mon Dec 10 18:58:19 MST 2007
Modified: branches/release/libs/iostreams/test/restrict_test.cpp
==============================================================================
--- branches/release/libs/iostreams/test/restrict_test.cpp	(original)
+++ branches/release/libs/iostreams/test/restrict_test.cpp	2008-01-13 02:33:37 EST (Sun, 13 Jan 2008)
@@ -4,30 +4,40 @@
 
 // See http://www.boost.org/libs/iostreams for documentation.
 
-// Todo: add tests for direct devices.
+// Allow this file to be used by slice_test.hpp. It is important not to 
+// replace BOOST_RESTRICT with BOOST_IOSTREAMS_RESTRICT here, since that
+// would interfere with the oepration of the header 
+// <boost/iostreams/restrict.hpp>
+
+#ifndef BOOST_RESTRICT
+# define BOOST_RESTRICT restrict
+# define BOOST_RESTRICT_HEADER <boost/iostreams/restrict.hpp>
+#endif
+#include BOOST_RESTRICT_HEADER
 
-#include <algorithm>  // equal.
+#include <algorithm>         // equal.
 #include <cctype>
-#include <iterator>   // back_inserter.
+#include <iterator>          // back_inserter.
 #include <vector>
 #include <boost/iostreams/copy.hpp>
 #include <boost/iostreams/device/file.hpp>
 #include <boost/iostreams/device/null.hpp>
 #include <boost/iostreams/filtering_stream.hpp>
-#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;
@@ -123,8 +133,8 @@
         test_file              src2;
         stream_offset          off = small_padding,
                                len = data_reps * data_length();
-        filtering_istream first( restrict( file_source(src1.name(), in_mode), 
-                                           off, len ) );
+        filtering_istream      first( 
+            BOOST_RESTRICT(file_source(src1.name(), in_mode), off, len));
         ifstream               second(src2.name().c_str(), in_mode);
         BOOST_CHECK_MESSAGE(
             compare_streams_in_chunks(first, second),
@@ -137,8 +147,8 @@
         test_file              src2;
         stream_offset          off = large_padding,
                                len = data_reps * data_length();
-        filtering_istream first( restrict( file_source(src1.name(), in_mode), 
-                                           off, len ) );
+        filtering_istream      first(
+            BOOST_RESTRICT(file_source(src1.name(), in_mode), off, len));
         ifstream               second(src2.name().c_str(), in_mode);
         BOOST_CHECK_MESSAGE(
             compare_streams_in_chunks(first, second),
@@ -150,7 +160,8 @@
         restricted_test_file   src1(small_padding, true);
         test_file              src2;
         stream_offset          off = small_padding;
-        filtering_istream first(restrict(file_source(src1.name(), in_mode), off));
+        filtering_istream      first(
+            BOOST_RESTRICT(file_source(src1.name(), in_mode), off));
         ifstream               second(src2.name().c_str(), in_mode);
         BOOST_CHECK_MESSAGE(
             compare_streams_in_chunks(first, second),
@@ -163,7 +174,8 @@
         restricted_test_file   src1(large_padding, true);
         test_file              src2;
         stream_offset          off = large_padding;
-        filtering_istream first(restrict(file_source(src1.name(), in_mode), off));
+        filtering_istream      first(
+            BOOST_RESTRICT(file_source(src1.name(), in_mode), off));
         ifstream               second(src2.name().c_str(), in_mode);
         BOOST_CHECK_MESSAGE(
             compare_streams_in_chunks(first, second),
@@ -181,7 +193,7 @@
         array_source              array_src(&src[0], &src[0] + src.size());
         stream_offset             off = small_padding,
                                   len = data_reps * data_length();
-        filtering_istream         second(restrict(array_src, off, len));
+        filtering_istream         second(BOOST_RESTRICT(array_src, off, len));
         BOOST_CHECK_MESSAGE(
             compare_container_and_stream(first, second),
             "failed reading from restriction<Direct>"
@@ -193,7 +205,7 @@
         restricted_test_sequence  src(small_padding, true);
         array_source              array_src(&src[0], &src[0] + src.size());
         stream_offset             off = small_padding;
-        filtering_istream         second(restrict(array_src, off));
+        filtering_istream         second(BOOST_RESTRICT(array_src, off));
         BOOST_CHECK_MESSAGE(
             compare_container_and_stream(first, second),
             "failed reading from half-open restriction<Direct>"
@@ -209,7 +221,7 @@
         stream_offset          off = small_padding,
                                len = data_reps * data_length();
         filtering_istream      first;
-        first.push(restrict(toupper_filter(), off, len));
+        first.push(BOOST_RESTRICT(toupper_filter(), off, len));
         first.push(file_source(src1.name(), in_mode));
         ifstream           second(src2.name().c_str(), in_mode);
         BOOST_CHECK_MESSAGE(
@@ -224,7 +236,7 @@
         stream_offset          off = large_padding,
                                len = data_reps * data_length();
         filtering_istream      first;
-        first.push(restrict(toupper_filter(), off, len));
+        first.push(BOOST_RESTRICT(toupper_filter(), off, len));
         first.push(file_source(src1.name(), in_mode));
         ifstream           second(src2.name().c_str(), in_mode);
         BOOST_CHECK_MESSAGE(
@@ -238,7 +250,7 @@
         uppercase_file         src2;
         stream_offset          off = small_padding;
         filtering_istream      first;
-        first.push(restrict(toupper_filter(), off));
+        first.push(BOOST_RESTRICT(toupper_filter(), off));
         first.push(file_source(src1.name(), in_mode));
         ifstream           second(src2.name().c_str(), in_mode);
         BOOST_CHECK_MESSAGE(
@@ -253,7 +265,7 @@
         uppercase_file         src2;
         stream_offset          off = large_padding;
         filtering_istream      first;
-        first.push(restrict(toupper_filter(), off));
+        first.push(BOOST_RESTRICT(toupper_filter(), off));
         first.push(file_source(src1.name(), in_mode));
         ifstream           second(src2.name().c_str(), in_mode);
         BOOST_CHECK_MESSAGE(
@@ -271,8 +283,8 @@
         restricted_test_file       dest2(small_padding);
         stream_offset              off = small_padding,
                                    len = data_reps * data_length();
-        filtering_ostream out( restrict( file(dest1.name(), BOOST_IOS::binary),
-                                         off, len ) );
+        filtering_ostream          out(
+            BOOST_RESTRICT(file(dest1.name(), BOOST_IOS::binary), off, len));
         write_data_in_chunks(out);
         out.reset();
         ifstream                   first(dest1.name().c_str(), in_mode);
@@ -288,8 +300,8 @@
         restricted_test_file       dest2(large_padding);
         stream_offset              off = large_padding,
                                    len = data_reps * data_length();
-        filtering_ostream out( restrict( file(dest1.name(), BOOST_IOS::binary), 
-                                         off, len ) );
+        filtering_ostream          out
+            (BOOST_RESTRICT(file(dest1.name(), BOOST_IOS::binary), off, len));
         write_data_in_chunks(out);
         out.reset();
         ifstream                   first(dest1.name().c_str(), in_mode);
@@ -304,7 +316,8 @@
         restricted_uppercase_file  dest1(small_padding, true);
         restricted_test_file       dest2(small_padding, true);
         stream_offset              off = small_padding;
-        filtering_ostream out(restrict(file(dest1.name(), BOOST_IOS::binary), off));
+        filtering_ostream          out
+            (BOOST_RESTRICT(file(dest1.name(), BOOST_IOS::binary), off));
         write_data_in_chunks(out);
         out.reset();
         ifstream                   first(dest1.name().c_str(), in_mode);
@@ -320,7 +333,8 @@
         restricted_uppercase_file  dest1(large_padding, true);
         restricted_test_file       dest2(large_padding, true);
         stream_offset              off = large_padding;
-        filtering_ostream out(restrict(file(dest1.name(), BOOST_IOS::binary), off));
+        filtering_ostream          out
+            (BOOST_RESTRICT(file(dest1.name(), BOOST_IOS::binary), off));
         write_data_in_chunks(out);
         out.reset();
         ifstream                   first(dest1.name().c_str(), in_mode);
@@ -343,7 +357,7 @@
         stream_offset             off = small_padding,
                                   len = data_reps * data_length();
         array_sink                array(&dest1[0], &dest1[0] + dest1.size());
-        filtering_ostream         out(restrict(array, off, len));
+        filtering_ostream         out(BOOST_RESTRICT(array, off, len));
         write_data_in_chunks(out);
         out.reset();
         BOOST_CHECK_MESSAGE(
@@ -353,12 +367,12 @@
     }
 
     {
-        vector<char>              dest1( data_reps * data_length() + small_padding,
-                                         '\n' );
+        vector<char>              dest1(
+            data_reps * data_length() + small_padding, '\n');
         restricted_test_sequence  dest2(small_padding, true);
         stream_offset             off = small_padding;
         array_sink                array(&dest1[0], &dest1[0] + dest1.size());
-        filtering_ostream         out(restrict(array, off));
+        filtering_ostream         out(BOOST_RESTRICT(array, off));
         write_data_in_chunks(out);
         out.reset();
         BOOST_CHECK_MESSAGE(
@@ -376,7 +390,7 @@
         stream_offset              off = small_padding,
                                    len = data_reps * data_length();
         filtering_ostream          out;
-        out.push(restrict(tolower_seekable_filter(), off, len));
+        out.push(BOOST_RESTRICT(tolower_seekable_filter(), off, len));
         out.push(file(dest1.name(), BOOST_IOS::binary));
         write_data_in_chunks(out);
         out.reset();
@@ -394,7 +408,7 @@
         stream_offset              off = large_padding,
                                    len = data_reps * data_length();
         filtering_ostream          out;
-        out.push(restrict(tolower_seekable_filter(), off, len));
+        out.push(BOOST_RESTRICT(tolower_seekable_filter(), off, len));
         out.push(file(dest1.name(), BOOST_IOS::binary));
         write_data_in_chunks(out);
         out.reset();
@@ -411,7 +425,7 @@
         restricted_lowercase_file  dest2(small_padding, true);
         stream_offset              off = small_padding;
         filtering_ostream          out;
-        out.push(restrict(tolower_seekable_filter(), off));
+        out.push(BOOST_RESTRICT(tolower_seekable_filter(), off));
         out.push(file(dest1.name(), BOOST_IOS::binary));
         write_data_in_chunks(out);
         out.reset();
@@ -428,7 +442,7 @@
         restricted_lowercase_file  dest2(large_padding, true);
         stream_offset              off = large_padding;
         filtering_ostream          out;
-        out.push(restrict(tolower_seekable_filter(), off));
+        out.push(BOOST_RESTRICT(tolower_seekable_filter(), off));
         out.push(file(dest1.name(), BOOST_IOS::binary));
         write_data_in_chunks(out);
         out.reset();
@@ -447,8 +461,8 @@
         restricted_test_file       src(large_padding);
         stream_offset              off = large_padding,
                                    len = data_reps * data_length();
-        filtering_stream<seekable> io( restrict( file(src.name(), BOOST_IOS::binary),
-                                                 off, len ) );
+        filtering_stream<seekable> io(
+            BOOST_RESTRICT(file(src.name(), BOOST_IOS::binary), off, len));
         BOOST_CHECK_MESSAGE(
             test_seekable_in_chunks(io),
             "failed seeking within restriction<Device>"
@@ -458,7 +472,8 @@
     {
         restricted_test_file       src(large_padding, true);
         stream_offset              off = large_padding;
-        filtering_stream<seekable> io(restrict(file(src.name(), BOOST_IOS::binary), off));
+        filtering_stream<seekable> io(
+            BOOST_RESTRICT(file(src.name(), BOOST_IOS::binary), off));
         BOOST_CHECK_MESSAGE(
             test_seekable_in_chunks(io),
             "failed seeking within half-open restriction<Device>"
@@ -469,11 +484,12 @@
 void seek_direct_device()
 {
     {
-        vector<char>               src(data_reps * data_length() + 2 * small_padding, '\n');
+        vector<char>               src(
+            data_reps * data_length() + 2 * small_padding, '\n');
         stream_offset              off = small_padding,
                                    len = data_reps * data_length();
         array                      ar(&src[0], &src[0] + src.size());
-        filtering_stream<seekable> io(restrict(ar, off, len));
+        filtering_stream<seekable> io(BOOST_RESTRICT(ar, off, len));
         BOOST_CHECK_MESSAGE(
             test_seekable_in_chars(io),
             "failed seeking within restriction<Direct> with small padding"
@@ -481,10 +497,11 @@
     }
 
     {
-        vector<char>               src(data_reps * data_length() + small_padding, '\n');
+        vector<char>               src(
+            data_reps * data_length() + small_padding, '\n');
         stream_offset              off = small_padding;
         array                      ar(&src[0], &src[0] + src.size());
-        filtering_stream<seekable> io(restrict(ar, off));
+        filtering_stream<seekable> io(BOOST_RESTRICT(ar, off));
         BOOST_CHECK_MESSAGE(
             test_seekable_in_chars(io),
             "failed seeking within half-open restriction<Direct> "
@@ -498,9 +515,9 @@
     {
         restricted_test_file       src(small_padding);
         stream_offset              off = large_padding,
-                                len = data_reps * data_length();
+                                   len = data_reps * data_length();
         filtering_stream<seekable> io;
-        io.push(restrict(identity_seekable_filter(), off, len));
+        io.push(BOOST_RESTRICT(identity_seekable_filter(), off, len));
         io.push(file(src.name(), BOOST_IOS::binary));
         BOOST_CHECK_MESSAGE(
             test_seekable_in_chars(io),
@@ -512,7 +529,7 @@
         restricted_test_file       src(small_padding, true);
         stream_offset              off = large_padding;
         filtering_stream<seekable> io;
-        io.push(restrict(identity_seekable_filter(), off));
+        io.push(BOOST_RESTRICT(identity_seekable_filter(), off));
         io.push(file(src.name(), BOOST_IOS::binary));
         BOOST_CHECK_MESSAGE(
             test_seekable_in_chars(io),
@@ -521,9 +538,138 @@
     }
 }
 
+void close_device()
+{
+    // Restrict a source
+    {
+        operation_sequence  seq;
+        chain<input>        ch;
+        ch.push(
+            io::BOOST_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::BOOST_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::BOOST_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::BOOST_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::BOOST_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::BOOST_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::BOOST_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::BOOST_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");
+    test_suite* test = 
+        BOOST_TEST_SUITE(BOOST_STRINGIZE(BOOST_RESTRICT) " test");
     test->add(BOOST_TEST_CASE(&read_device));
     test->add(BOOST_TEST_CASE(&read_direct_device));
     test->add(BOOST_TEST_CASE(&read_filter));
@@ -532,5 +678,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: branches/release/libs/iostreams/test/stream_offset_64bit_test.cpp
==============================================================================
--- branches/release/libs/iostreams/test/stream_offset_64bit_test.cpp	(original)
+++ branches/release/libs/iostreams/test/stream_offset_64bit_test.cpp	2008-01-13 02:33:37 EST (Sun, 13 Jan 2008)
@@ -13,8 +13,11 @@
  * with large (64-bit) file offsets.
  */
 
+#include <cstdio>            // fpos_t
+#include <iostream>
 #include <sstream>
 #include <boost/config.hpp>  // BOOST_MSVC
+#include <boost/iostreams/detail/ios.hpp>
 #include <boost/iostreams/positioning.hpp>
 #include <boost/test/test_tools.hpp>
 #include <boost/test/unit_test.hpp>
@@ -29,7 +32,7 @@
 #endif
 
 void stream_offset_64bit_test()
-{    
+{
     stream_offset  large_file = (stream_offset) 100 *
                                 (stream_offset) 1024 *
                                 (stream_offset) 1024 *
@@ -40,11 +43,18 @@
     for (stream_offset off = first; off < last; off += 10000000)
     {
         if (off != position_to_offset(offset_to_position(off))) {
+            cout << "****************************************\n"
+                 << "* sizeof(fpos_t) = " << sizeof(fpos_t) << "\n"
+                 << "* sizeof(streamoff) = " << sizeof(streamoff) << "\n"
+                 << "* sizeof(stream_offset) = " 
+                 << sizeof(stream_offset) << "\n"
+                 << "****************************************\n";
             stringstream s;
             s << "off != position_to_offset(offset_to_position(off)) "
-                 "failed for (off >> 32) == " 
+                 "failed for (off >> 32) == 0x" 
+              << hex
               << static_cast<unsigned int>(off >> 32) 
-              << " and (off & 0xFFFFFFFF) == "
+              << " and (off & 0xFFFFFFFF) == 0x"
               << static_cast<unsigned int>(off & 0xFFFFFFFF);
             BOOST_REQUIRE_MESSAGE(0, s.str().c_str());
         }
Modified: branches/release/libs/iostreams/test/symmetric_filter_test.cpp
==============================================================================
--- branches/release/libs/iostreams/test/symmetric_filter_test.cpp	(original)
+++ branches/release/libs/iostreams/test/symmetric_filter_test.cpp	2008-01-13 02:33:37 EST (Sun, 13 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: branches/release/libs/iostreams/test/tee_test.cpp
==============================================================================
--- branches/release/libs/iostreams/test/tee_test.cpp	(original)
+++ branches/release/libs/iostreams/test/tee_test.cpp	2008-01-13 02:33:37 EST (Sun, 13 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;
 }