multiple close

close()の調査をしていてビックリしました。
次のコードを見てください。

#include <boost/iostreams/chain.hpp>
#include <iostream>

namespace io = boost::iostreams;

struct test_sink
{
    typedef char char_type;

    struct category : io::output, io::device_tag, io::closable_tag {};

    std::streamsize write(const char* s, std::streamsize n)
    {
        return n;
    }

    void close()
    {
        std::cout << "called test_sink::close()" << std::endl;
    }
};

int main()
{
    io::chain<io::output> out;
    out.push(test_sink());
}

これを実行するとclose()が二度呼ばれているのが分かります。
Boost-usersでも似た報告が見つかりました。
http://lists.boost.org/boost-users/2006/04/19128.php


コードを追ってみたところ、auto_closeによってindirect_streambuf::close(std::ios_base::out)が呼ばれた後、stream_bufferのデストラクタでindirect_streambuf::close()が呼ばれていました。
要するに、outだけ閉じた後でinとoutを閉じているので、outが二度閉じられているわけです。
indirect_streambufのバグだとは思いますが、close()のインタフェースを考える(is_open()ではin/outのどちらかが閉じられていることが分からない等)と似たケースは他にも発生しそうな気がします。
現時点では多重close()可能にしておいたほうがよさそうです。