# Function Template `close`

Description
When is `close` invoked?
Headers
Reference

## Description

The Iostreams library provides three overloads of the function template `close`.

The first overload of `close` takes a single Device argument. It allows a user to close a Device without worrying whether the Device controls a single sequence or two sequences:

    namespace boost { namespace iostreams {

    template<typename T>
    void close(T& t);

    } } // End namespace boost::io

The other two overloads of `close` should rarely be called by library users; they are invoked automatically by the library to indicate to Filters and Devices that a sequence of data is about to end. This gives Filters and Devices an opportunity to free resources or to reset their states in preparation for a new character sequence. Filters and Devices which perform output can use the opportunity to write additional data to the end of a stream.

The details regarding when and how `close` is invoked are a bit messy:

## When is `close` invoked?

#### `stream_buffer` and `stream`

When an instance of `stream_buffer` or `stream` based on a Device `d` is closed using member function `close`, the following sequence of functions calls is made:

        boost::iostreams::close(d, std::ios_base::in);
        boost::iostreams::close(d, std::ios_base::out);

The effect, if `D` is Closable and controls a single sequence, is as follows:

        d.close();

If `D` is Closable and controls separate input and output sequences, the effect is as follows:

        d.close(std::ios_base::in);
        d.close(std::ios_base::out);

(See the semantics of `close` for Device types, below.)

#### `filtering_streambuf` and `filtering_stream`

A `filtering_streambuf` or `filtering_stream` is considered to be closed if its lifetime ends while its chain is complete or if its terminal Device is removed using `pop` or `reset`. When this occurs, the following sequence of calls is made, assuming that the underlying sequence of Filters and Devices is `f1`, `f1`, ..., `fn-1`, `d` and the corresponding sequence of stream buffers is `buf1`, `buf2`, ..., `bufn-1`, `bufn`:[1]

        using namespace std;

        // Close each input sequence, in reverse order:
        boost::iostreams::close(d,n-1, bufn-1 ios_base::in);
        boost::iostreams::close(fn-1, bufn,-1 ios_base::in);
        boost::iostreams::close(fn-2, bufn-1, ios_base::in);
        ...
        boost::iostreams::close(f1,n- buf2,n- ios_base::in);

        // Close each output sequence, in order:
        boost::iostreams::close(f1,n- buf2,n- ios_base::out);
        boost::iostreams::close(f2,n- buf3,n- ios_base::out);
        ...
        boost::iostreams::close(fn-1, bufn,n- ios_base::out);
        boost::iostreams::close(d,n-1, bufn-1 ios_base::out);

This implies

- For filter chains consisting of read-only components, the elements of the chain are closed in reverse order
- For filter chains consisting of write-only components, the elements of the chain are closed in forward order
- Filters and Devices controlling separate input and output sequences receive two closure notifications, the first with argument `ios_base::in` and the second with argument `ios_base::out`.

(See the semantics of `close` for Filter and Device types, below.)

## Headers

`<boost/iostreams/close.hpp>`
`<boost/iostreams/operations.hpp>`

## Reference

### Synopsis

    namespace boost { namespace iostreams {

    template<typename T>
    void close(T& t);

    template<typename T>
    void close(T& t, std::ios_base::openmode which);

    template<typename T, typename Device>
    void close(T& t, Device& next, std::ios_base::openmode which);

    } } // End namespace boost::io

### Function Template `close` — Convenience Function

#### Template Parameters

T | - | A model of one of the Device concepts.

#### Semantics

    template<typename T>
    void close(T& t);

This overload of `close` calls `close(t, std::ios_base::in)` followed by `close(t, std::ios_base::out)`. It ensures that `t` is closed properly, regardless of the mode or `t`.

### Function Template `close` — Closure Notification for Devices

#### Template Parameters

T | - | A model of one of the Device concepts.

#### Semantics

    template<typename T>
    void close(T& t, std::ios_base::openmode which);

If `t` is a filtering stream or stream buffer, `close` calls `pop` if `t` is complete. The semantics depends on its category as follows:

`category<T>::type` | semantics
--- | ---
convertible to `input` but not to `output` | calls `t.pop()` if `t` is complete and which == ios_base::in
otherwise | calls `t.pop()` if `t` is complete and `which == ios_base::out`

The semantics of `close` for a device `T` other than a filtering stream or stream buffer depends on its category as follows:

`category<T>::type` | semantics
--- | ---
not convertible to `closable_tag` | calls `flush`
convertible to `closable_tag` and to `bidirectional` | calls `t.close(which)`
convertible to `closable_tag` and to `input` but not to `output` | calls `t.close()` if `which == ios_base::in`
convertible to `closable_tag` and to `output` but not to `bidirectional` | calls `t.close()` if `which == ios_base::out`

In short:

- If `T` is not Closable, `close` calls `flush`.
- If `T` is Closable and controls two separate sequences, `close` delegates to a member function `close` taking a single `openmode` parameter.
- Otherwise, `close` delegates to a member function `close` taking no parameters, but only if its `openmode` parameter is consistent with the mode of `T`.

The last condition prevents a Device controlling a single sequence from being closed twice in succession.

NOTE: Starting with Boost 1.35, the invocation of this function with an `openmode` other than `std::ios_base::in` or `std::ios_base::out` is deprecated. To close both sequences at once, use

    close(t)

instead of

    close(t, std::ios_base::in | std::ios_base::out)

### Function Template `close` — Closure Notification for Filters

#### Template Parameters

T | - | A model of one of the Filter concepts
Device | - | A Blocking Device whose mode refines that of `T`.

#### Semantics

    template<typename T, typename Device>
    void close(T& t, Device& next, std::ios_base::openmode which);

The semantics of `close` for a Filter type `T` depends on its category as follows:

`category<T>::type` | semantics
--- | ---
not convertible to `closable_tag` | calls `flush`
convertible to `closable_tag` and to `bidirectional` | calls `t.close(next, which)`
convertible to `closable_tag` and to `input` but not to `output` | calls `t.close(next)` if `which == ios_base::in`
convertible to `closable_tag` and to `output` but not to `bidirectional` | calls `t.close(next)` if `which == ios_base::out`

In short:

- If `T` is not Closable, `close` calls `flush`.
- If `T` is Closable and controls two separate sequences, `close` delegates to a member function `close` taking `openmode` and stream buffer parameters.
- Otherwise, `close` delegates to a member function `close` taking a single stream buffer parameter, but only if its `openmode` parameter is consistent with the mode of `T`.

The last condition prevents a Filter controlling a single sequence from being closed twice in succession.

NOTE: Starting with Boost 1.35, the invocation of this function with an `openmode` other than `std::ios_base::in` or `std::ios_base::out` is deprecated.

[1]This behavior can be disabled in the case of `pop` by calling member function `set_auto_close` with the argument `false`. See, e.g., `filtering_stream::set_auto_close`.

Revised 02 Feb 2008

© Copyright 2008 CodeRage, LLC
© Copyright 2004-2007 Jonathan Turkanis

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)