|
Boost-Commit : |
From: technews_at_[hidden]
Date: 2007-12-25 20:07:13
Author: turkanis
Date: 2007-12-25 20:07:12 EST (Tue, 25 Dec 2007)
New Revision: 42305
URL: http://svn.boost.org/trac/boost/changeset/42305
Log:
Resolved issue #1033 (iostreams)
restrict.hpp:
- added static asserts to prevent using restrict with bidirectional filters
and devices (since it would not be clear which of the two sequences is to
be restricted). To restrict a bidirectional component, combine the
restrictions of a read-only and a write-only view of the component, using
combine() and detail::mode_adapter (which should probably be made public)
- added special treatment for dual_use filters, to make sure the "which"
argument to seek is set correctly (although I don't know of any examples
of seekable dual use filters)
skip.hpp:
- added a "which" parameter to skip() for filters
- added more fine-grained analysis of modes to determine whether to call
the optimized version of detail::skip()
- added static asserts to rule out the case where skip is called with
a non-seekable output-only device
test/close_test.cpp
- removed uses of restrict with bidirectional devices, since this doesn't
make sense and is now officially prohibited
Text files modified:
branches/iostreams_dev/boost/iostreams/restrict.hpp | 37 +++++++++++++++++++++----
branches/iostreams_dev/boost/iostreams/skip.hpp | 49 +++++++++++++++++++++++++---------
branches/iostreams_dev/libs/iostreams/test/close_test.cpp | 57 ----------------------------------------
3 files changed, 66 insertions(+), 77 deletions(-)
Modified: branches/iostreams_dev/boost/iostreams/restrict.hpp
==============================================================================
--- branches/iostreams_dev/boost/iostreams/restrict.hpp (original)
+++ branches/iostreams_dev/boost/iostreams/restrict.hpp 2007-12-25 20:07:12 EST (Tue, 25 Dec 2007)
@@ -49,9 +49,11 @@
private:
typedef typename detail::param_type<Device>::type param_type;
public:
- typedef typename char_type_of<Device>::type char_type;
+ 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_of<Device>::type,
+ : mode,
device_tag,
closable_tag,
flushable_tag,
@@ -78,6 +80,8 @@
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,
@@ -105,8 +109,10 @@
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_of<Filter>::type,
+ : mode,
filter_tag,
multichar_tag,
closable_tag,
@@ -121,7 +127,7 @@
{
using namespace std;
if (!open_)
- open(src);
+ open(src, BOOST_IOS::in);
streamsize amt =
end_ != -1 ?
(std::min) (n, static_cast<streamsize>(end_ - pos_)) :
@@ -136,7 +142,7 @@
std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
{
if (!open_)
- open(snk);
+ open(snk, BOOST_IOS::out);
if (end_ != -1 && pos_ + n >= end_)
bad_write();
std::streamsize result =
@@ -167,13 +173,30 @@
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)
+ void open(Device& dev, BOOST_IOS::openmode which)
{
+ typedef typename is_convertible<mode, dual_use>::type is_dual_use;
open_ = true;
- iostreams::skip(this->component(), dev, beg_);
+ 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_;
};
Modified: branches/iostreams_dev/boost/iostreams/skip.hpp
==============================================================================
--- branches/iostreams_dev/boost/iostreams/skip.hpp (original)
+++ branches/iostreams_dev/boost/iostreams/skip.hpp 2007-12-25 20:07:12 EST (Tue, 25 Dec 2007)
@@ -16,9 +16,11 @@
#include <boost/iostreams/char_traits.hpp>
#include <boost/iostreams/detail/ios.hpp> // failure.
#include <boost/iostreams/operations.hpp>
+#include <boost/iostreams/seek.hpp>
#include <boost/iostreams/traits.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/bool.hpp>
+#include <boost/mpl/or.hpp>
#include <boost/type_traits/is_convertible.hpp>
namespace boost { namespace iostreams {
@@ -44,11 +46,13 @@
}
template<typename Filter, typename Device>
-void skip(Filter& flt, Device& dev, stream_offset off, mpl::true_)
-{ flt.seek(dev, off, BOOST_IOS::cur); }
+void skip( Filter& flt, Device& dev, stream_offset off,
+ BOOST_IOS::openmode which, mpl::true_ )
+{ boost::iostreams::seek(flt, dev, off, BOOST_IOS::cur, which); }
template<typename Filter, typename Device>
-void skip(Filter& flt, Device& dev, stream_offset off, mpl::false_)
+void skip( Filter& flt, Device& dev, stream_offset off,
+ BOOST_IOS::openmode, mpl::false_ )
{
typedef typename char_type_of<Device>::type char_type;
char_type c;
@@ -66,20 +70,39 @@
template<typename Device>
void skip(Device& dev, stream_offset off)
{
- typedef typename mode_of<Device>::type mode;
- detail::skip(dev, off, is_convertible<mode, seekable>());
+ typedef typename mode_of<Device>::type mode;
+ typedef mpl::or_<
+ is_convertible<mode, input_seekable>,
+ is_convertible<mode, output_seekable>
+ > can_seek;
+ BOOST_STATIC_ASSERT(
+ (can_seek::value || is_convertible<mode, input>::value)
+ );
+ detail::skip(dev, off, can_seek());
}
template<typename Filter, typename Device>
-void skip(Filter& flt, Device& dev, stream_offset off)
+void skip( Filter& flt, Device& dev, stream_offset off,
+ BOOST_IOS::openmode which = BOOST_IOS::in | BOOST_IOS::out )
{
- typedef typename mode_of<Filter>::type filter_mode;
- typedef typename mode_of<Device>::type device_mode;
- typedef mpl::and_<
- is_convertible<filter_mode, output_seekable>,
- is_convertible<device_mode, output_seekable>
- > can_seek;
- detail::skip(flt, dev, off, can_seek());
+ typedef typename mode_of<Filter>::type filter_mode;
+ typedef typename mode_of<Device>::type device_mode;
+ typedef mpl::or_<
+ mpl::and_<
+ is_convertible<filter_mode, input_seekable>,
+ is_convertible<device_mode, input_seekable>
+ >,
+ mpl::and_<
+ is_convertible<filter_mode, output_seekable>,
+ is_convertible<device_mode, output_seekable>
+ >
+ > can_seek;
+ BOOST_STATIC_ASSERT(
+ ( can_seek::value ||
+ is_convertible<filter_mode, input>::value &&
+ is_convertible<device_mode, input>::value )
+ );
+ detail::skip(flt, dev, off, which, can_seek());
}
} } // End namespaces iostreams, boost.
Modified: branches/iostreams_dev/libs/iostreams/test/close_test.cpp
==============================================================================
--- branches/iostreams_dev/libs/iostreams/test/close_test.cpp (original)
+++ branches/iostreams_dev/libs/iostreams/test/close_test.cpp 2007-12-25 20:07:12 EST (Tue, 25 Dec 2007)
@@ -1062,23 +1062,6 @@
BOOST_CHECK_OPERATION_SEQUENCE(seq);
}
- // Restrict a bidirectional device
- {
- operation_sequence seq;
- chain<bidirectional> ch;
- ch.push(
- io::restrict(
- closable_device<bidirectional>(
- seq.new_operation(1),
- seq.new_operation(2)
- ),
- 0
- )
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
// Restrict a seekable device
{
operation_sequence seq;
@@ -1101,23 +1084,6 @@
BOOST_CHECK_OPERATION_SEQUENCE(seq);
}
- // Restrict a direct bidirectional device
- {
- operation_sequence seq;
- chain<bidirectional> ch;
- ch.push(
- io::restrict(
- closable_device<direct_bidirectional>(
- seq.new_operation(1),
- seq.new_operation(2)
- ),
- 0
- )
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
// Restrict a direct seekable device
{
operation_sequence seq;
@@ -1142,29 +1108,6 @@
BOOST_CHECK_OPERATION_SEQUENCE(seq);
}
- // Restrict a bidirectional filter
- {
- operation_sequence seq;
- chain<bidirectional> ch;
- ch.push(
- io::restrict(
- closable_filter<bidirectional>(
- seq.new_operation(2),
- seq.new_operation(3)
- ),
- 0
- )
- );
- ch.push(
- closable_device<bidirectional>(
- seq.new_operation(1),
- seq.new_operation(4)
- )
- );
- BOOST_CHECK_NO_THROW(ch.reset());
- BOOST_CHECK_OPERATION_SEQUENCE(seq);
- }
-
// Restrict a seekable filter
{
operation_sequence seq;
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk